changeset 10200:748207aa9620

Merge
author lana
date Tue, 08 Oct 2013 14:57:32 -0700
parents c1ef9ebac26a (current diff) 95bb56c61276 (diff)
children 575d4bc3bcae
files makefiles/CompileJavaClasses.gmk makefiles/CreateJars.gmk src/share/classes/java/lang/invoke/InvokeGeneric.java src/share/classes/java/time/chrono/ChronoDateImpl.java test/java/time/tck/java/time/chrono/TCKChronologySerialization.java
diffstat 265 files changed, 12825 insertions(+), 3613 deletions(-) [+]
line wrap: on
line diff
--- a/make/docs/Makefile	Tue Oct 08 14:53:14 2013 -0700
+++ b/make/docs/Makefile	Tue Oct 08 14:57:32 2013 -0700
@@ -50,6 +50,7 @@
 DEV_DOCS_URL-5 = http://java.sun.com/j2se/1.5.0/docs/index.html
 DEV_DOCS_URL-6 = http://download.oracle.com/javase/6/docs/index.html
 DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html
+DEV_DOCS_URL-8 = http://download.oracle.com/javase/8/docs/index.html
 DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION))
 DOCS_BASE_URL = http://download.oracle.com/javase/7/docs
 
--- a/make/java/java/FILES_c.gmk	Tue Oct 08 14:53:14 2013 -0700
+++ b/make/java/java/FILES_c.gmk	Tue Oct 08 14:57:32 2013 -0700
@@ -33,6 +33,7 @@
 	Console_md.c \
 	Double.c \
 	Executable.c \
+	Field.c \
 	FileDescriptor_md.c \
 	FileInputStream.c \
 	FileInputStream_md.c \
--- a/make/java/java/mapfile-vers	Tue Oct 08 14:53:14 2013 -0700
+++ b/make/java/java/mapfile-vers	Tue Oct 08 14:57:32 2013 -0700
@@ -190,6 +190,8 @@
 		Java_java_lang_reflect_Array_setLong;
 		Java_java_lang_reflect_Array_setShort;
 		Java_java_lang_reflect_Executable_getParameters0;
+		Java_java_lang_reflect_Executable_getTypeAnnotationBytes0;
+		Java_java_lang_reflect_Field_getTypeAnnotationBytes0;
 		Java_java_lang_Runtime_freeMemory;
                 Java_java_lang_Runtime_maxMemory;
 		Java_java_lang_Runtime_gc;
--- a/make/netbeans/common/java-data-native.ent	Tue Oct 08 14:53:14 2013 -0700
+++ b/make/netbeans/common/java-data-native.ent	Tue Oct 08 14:57:32 2013 -0700
@@ -31,14 +31,14 @@
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
 
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
     <compilation-unit>
         <package-root>${root}/src/share/classes</package-root>
         <package-root>${root}/src/macosx/classes</package-root>
         <package-root>${root}/src/solaris/classes</package-root>
         <package-root>${root}/src/windows/classes</package-root>
         <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
-        <built-to>${root}/build/${platform}-${arch}/classes</built-to>
+        <built-to>${root}/../build/${platform}-${arch}/jdk/classes</built-to>
         <javadoc-built-to>${root}/build/${platform}-${arch}/docs/api</javadoc-built-to>
         <source-level>1.8</source-level>
     </compilation-unit>
--- a/make/netbeans/common/java-data-no-native.ent	Tue Oct 08 14:53:14 2013 -0700
+++ b/make/netbeans/common/java-data-no-native.ent	Tue Oct 08 14:57:32 2013 -0700
@@ -31,11 +31,11 @@
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 -->
 
-<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3">
+<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
     <compilation-unit>
         <package-root>${root}/src/share/classes</package-root>
         <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
-        <built-to>${root}/build/${platform}-${arch}/classes</built-to>
+        <built-to>${root}/../build/${platform}-${arch}/jdk/classes</built-to>
         <javadoc-built-to>${root}/build/${platform}-${arch}/docs/api</javadoc-built-to>
         <source-level>1.8</source-level>
     </compilation-unit>
--- a/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java	Tue Oct 08 14:57:32 2013 -0700
@@ -174,6 +174,44 @@
     private HashMap<String, HashSet<String>> knownPrefixMap = new HashMap<>();
 
     /*
+     * A class for mapping package prefixes to the number of
+     * levels of package elements to include.
+     */
+    static class ExtraLevel {
+        public ExtraLevel(String prefix, int levels) {
+            this.prefix = prefix;
+            this.levels = levels;
+        }
+        String prefix;
+        int levels;
+    }
+
+    /*
+     * A list of the special-cased package names.
+     */
+    private static ArrayList<ExtraLevel> extraLevels = new ArrayList<>();
+
+    static {
+        // The order of these statements is significant,
+        // since we stop looking after the first match.
+
+        // Need more precise information to disambiguate
+        // (illegal) references from applications to
+        // obsolete backported collections classes in
+        // com/sun/java/util
+        extraLevels.add(new ExtraLevel("com/sun/java/util/", Integer.MAX_VALUE));
+        extraLevels.add(new ExtraLevel("com/sun/java/", 4));
+        // Need more information than just first two package
+        // name elements to determine that classes in
+        // deploy.jar are not in rt.jar
+        extraLevels.add(new ExtraLevel("com/sun/", 3));
+        // Need to make sure things in jfr.jar aren't
+        // confused with other com/oracle/** packages
+        extraLevels.add(new ExtraLevel("com/oracle/jrockit", 3));
+    }
+
+
+    /*
      * We add maximum 5 second level entries to "sun", "java" and
      * "javax" entries. Tune this parameter to get a balance on the
      * cold start and footprint.
@@ -237,39 +275,25 @@
                         String[] pkgElements = name.split("/");
                         // Last one is the class name; definitely ignoring that
                         if (pkgElements.length > 2) {
-                            String meta = null;
-                            // Need more information than just first two package
-                            // name elements to determine that classes in
-                            // deploy.jar are not in rt.jar
-                            if (pkgElements.length > 3 &&
-                                pkgElements[0].equals("com") &&
-                                pkgElements[1].equals("sun")) {
-                                // Need more precise information to disambiguate
-                                // (illegal) references from applications to
-                                // obsolete backported collections classes in
-                                // com/sun/java/util
-                                if (pkgElements.length > 4 &&
-                                    pkgElements[2].equals("java")) {
-                                    int bound = 0;
-                                    if (pkgElements[3].equals("util")) {
-                                        // Take all of the packages
-                                        bound = pkgElements.length - 1;
-                                    } else {
-                                        // Trim it somewhat more
-                                        bound = 4;
-                                    }
-                                    meta = "";
-                                    for (int j = 0; j < bound; j++) {
-                                        meta += pkgElements[j] + "/";
-                                    }
-                                } else {
-                                    meta = pkgElements[0] + "/" + pkgElements[1]
-                                        + "/" + pkgElements[2] + "/";
+                            String meta = "";
+
+                            // Default is 2 levels of package elements
+                            int levels = 2;
+
+                            // But for some packages we add more elements
+                            for(ExtraLevel el : extraLevels) {
+                                if (name.startsWith(el.prefix)) {
+                                    levels = el.levels;
+                                    break;
                                 }
-                            } else {
-                                meta = pkgElements[0] + "/" + pkgElements[1] + "/";
+                            }
+                            for (int i = 0; i < levels && i < pkgElements.length - 1; i++) {
+                                meta += pkgElements[i] + "/";
                             }
-                            indexSet.add(meta);
+
+                            if (!meta.equals("")) {
+                                indexSet.add(meta);
+                            }
                         }
 
                     } // end of "while" loop;
--- a/makefiles/CompileJavaClasses.gmk	Tue Oct 08 14:53:14 2013 -0700
+++ b/makefiles/CompileJavaClasses.gmk	Tue Oct 08 14:57:32 2013 -0700
@@ -237,10 +237,10 @@
 
 # These files do not appear in the build result of the old build. This
 # is because they are generated sources, but the AUTO_JAVA_FILES won't
-# pick them up since they aren't generated when the source dirs are 
+# pick them up since they aren't generated when the source dirs are
 # searched and they aren't referenced by any other classes so they won't
 # be picked up by implicit compilation. On a rebuild, they are picked up
-# and compiled. Exclude them here to produce the same rt.jar as the old 
+# and compiled. Exclude them here to produce the same rt.jar as the old
 # build does when building just once.
 EXFILES+=javax/swing/plaf/nimbus/InternalFrameTitlePanePainter.java \
 	 javax/swing/plaf/nimbus/OptionPaneMessageAreaPainter.java \
@@ -308,19 +308,6 @@
 
 ##########################################################################################
 
-ifndef OPENJDK
-
-    $(eval $(call SetupJavaCompilation,BUILD_ALTCLASSES,\
-		SETUP:=GENERATE_JDKBYTECODE,\
-		SRC:=$(JDK_TOPDIR)/src/closed/share/altclasses, \
-		BIN:=$(JDK_OUTPUTDIR)/altclasses_classes))
-
-    $(BUILD_ALTCLASSES): $(BUILD_JDK)
-
-endif
-
-##########################################################################################
-
 $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin:
 	$(MKDIR) -p $(@D)
 	$(TOUCH) $@
@@ -403,7 +390,7 @@
 
 ##########################################################################################
 
-all: $(BUILD_JDK) $(BUILD_ALTCLASSES) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \
+all: $(BUILD_JDK) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \
 	$(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin \
 	$(BUILD_ACCESSBRIDGE_32) $(BUILD_ACCESSBRIDGE_64) \
 	$(BUILD_ACCESSBRIDGE_LEGACY)
--- a/makefiles/CreateJars.gmk	Tue Oct 08 14:53:14 2013 -0700
+++ b/makefiles/CreateJars.gmk	Tue Oct 08 14:57:32 2013 -0700
@@ -1003,15 +1003,6 @@
 
 ##########################################################################################
 
-ifndef OPENJDK
-    $(eval $(call SetupArchive,BUILD_ALT_RT_JAR,,\
-		SRCS:=$(JDK_OUTPUTDIR)/altclasses_classes,\
-		JAR:=$(IMAGES_OUTPUTDIR)/lib/alt-rt.jar))
-
-endif
-
-##########################################################################################
-
 # This file is imported from hotspot in Import.gmk. Copying it into images/lib so that
 # all jars can be found in one place when creating images in Images.gmk. It needs to be
 # done here so that clean targets can be simple and accurate.
--- a/makefiles/Profiles.gmk	Tue Oct 08 14:53:14 2013 -0700
+++ b/makefiles/Profiles.gmk	Tue Oct 08 14:57:32 2013 -0700
@@ -40,8 +40,8 @@
 # imported (signed jars) rather than built.
 #
 # The incoming lists, eg PROFILE_1_JRE_JARS_FILES, are the jars to be
-# included in this profile. They have the jar name relative to the lib 
-# directory. We have to turn these into targets by adding the 
+# included in this profile. They have the jar name relative to the lib
+# directory. We have to turn these into targets by adding the
 # $(IMAGES_OUTPUTDIR)/lib prefix
 #
 # Note that some jars may be optional depending on the type of build (jdk vs.
@@ -69,10 +69,6 @@
     $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \
     $(PROFILE_2_JARS)
 
-ifdef OPENJDK
-  FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES))
-endif
-
 ifneq ($(ENABLE_JFR), true)
   FULL_JRE_JAR_FILES :=  $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES))
 endif
@@ -107,7 +103,7 @@
 
 ifeq ($(OPENJDK_TARGET_OS),windows)
     ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar
-endif 
+endif
 
 ifeq ($(OPENJDK_TARGET_OS),macosx)
     ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar
@@ -142,7 +138,7 @@
    $(PROFILE_1_JRE_BIN_FILES) \
    $(PROFILE_2_JRE_BIN_FILES) \
    $(PROFILE_3_JRE_BIN_FILES) \
-   $(FULL_JRE_BIN_FILES) 
+   $(FULL_JRE_BIN_FILES)
 
 NOT_JRE_BIN_FILES := $(filter-out $(ALL_JRE_BIN_FILES), $(NEW_ALL_BIN_LIST))
 
@@ -151,18 +147,18 @@
     NOT_JRE_BIN_FILES += \
         $(PROFILE_2_JRE_BIN_FILES) \
         $(PROFILE_3_JRE_BIN_FILES) \
-        $(FULL_JRE_BIN_FILES) 
+        $(FULL_JRE_BIN_FILES)
 endif
 
 ifeq ($(PROFILE), profile_2)
     NOT_JRE_BIN_FILES += \
         $(PROFILE_3_JRE_BIN_FILES) \
-        $(FULL_JRE_BIN_FILES) 
+        $(FULL_JRE_BIN_FILES)
 endif
 
 ifeq ($(PROFILE), profile_3)
     NOT_JRE_BIN_FILES += \
-        $(FULL_JRE_BIN_FILES) 
+        $(FULL_JRE_BIN_FILES)
 endif
 
 NOT_JRE_BIN_FILES := $(addprefix $(JDK_OUTPUTDIR)/bin/, $(NOT_JRE_BIN_FILES))
@@ -175,7 +171,7 @@
    $(PROFILE_1_JRE_LIB_FILES) \
    $(PROFILE_2_JRE_LIB_FILES) \
    $(PROFILE_3_JRE_LIB_FILES) \
-   $(FULL_JRE_LIB_FILES) 
+   $(FULL_JRE_LIB_FILES)
 
 NOT_JRE_LIB_FILES := $(filter-out $(ALL_JRE_LIB_FILES), $(NEW_ALL_LIB_LIST))
 
@@ -191,18 +187,18 @@
     NOT_JRE_LIB_FILES += \
         $(PROFILE_2_JRE_LIB_FILES) \
         $(PROFILE_3_JRE_LIB_FILES) \
-        $(FULL_JRE_LIB_FILES) 
+        $(FULL_JRE_LIB_FILES)
 endif
 
 ifeq ($(PROFILE), profile_2)
     NOT_JRE_LIB_FILES += \
         $(PROFILE_3_JRE_LIB_FILES) \
-        $(FULL_JRE_LIB_FILES) 
+        $(FULL_JRE_LIB_FILES)
 endif
 
 ifeq ($(PROFILE), profile_3)
     NOT_JRE_LIB_FILES += \
-        $(FULL_JRE_LIB_FILES) 
+        $(FULL_JRE_LIB_FILES)
 endif
 
 # Exclude the custom jar files as these will be added back via a special rule
@@ -210,7 +206,7 @@
 
 ###############################################################################
 # Customization of rt.jar file contents
-# These are expressed as exclusions from everything found in the 
+# These are expressed as exclusions from everything found in the
 # JDK_OUTPUTDIR/classes directory
 ###############################################################################
 
@@ -231,8 +227,8 @@
 #
 # These are specific types that must be included within a package.
 # There are two cases:
-# - individual types in a package that is otherwise excluded at this 
-#   profile level. The only arises if there are split packages. 
+# - individual types in a package that is otherwise excluded at this
+#   profile level. The only arises if there are split packages.
 #
 # - A higher-level package is included in a high profile where a subpackage
 # is included in a lower profile. Including the package in the high profile
@@ -247,7 +243,7 @@
 # containing package is include. Again this occurs with split packges.
 #
 # So the exclude list for each profile consists of the include lists
-# for all profiles above it, together with any explicitly excluded types. 
+# for all profiles above it, together with any explicitly excluded types.
 # This is then combined with the overall RT_JAR_EXCLUDES list (which covers
 # things that go into other jar files).
 #
@@ -257,7 +253,7 @@
 # profile 3 includes the entire package, but it is harmless to add them
 # explicitly, and complex to determine if we still need to include them.
 #
-# Need a way to express: 
+# Need a way to express:
 #  for (int i = profile+1; i < 4; i++)
 #     RT_JAR_EXCLUDES += PROFILE_$i_RTJAR_INCLUDE_PACKAGES
 #
@@ -267,7 +263,7 @@
 #
 # These are META-INF/services/ entries found in resources.jar. Together
 # resources.jar and rt.jar hold the contents of the classes directory, (the
-# classes in rt.jar and everything else in resources.jar).Hence the 
+# classes in rt.jar and everything else in resources.jar).Hence the
 # include/exclude information for resources.jar is tied to that of rt.jar
 
 include profile-rtjar-includes.txt
@@ -324,7 +320,7 @@
 
 # Filter out non-OpenJDK services
 ifdef OPENJDK
-  EXCLUDED_SERVICES := META-INF/services/javax.script.ScriptEngineFactory 
+  EXCLUDED_SERVICES := META-INF/services/javax.script.ScriptEngineFactory
   PROFILE_INCLUDE_METAINF_SERVICES := $(filter-out $(EXCLUDED_SERVICES),$(PROFILE_INCLUDE_METAINF_SERVICES))
 endif
 
--- a/makefiles/mapfiles/libjava/mapfile-vers	Tue Oct 08 14:53:14 2013 -0700
+++ b/makefiles/mapfiles/libjava/mapfile-vers	Tue Oct 08 14:57:32 2013 -0700
@@ -190,6 +190,8 @@
 		Java_java_lang_reflect_Array_setLong;
 		Java_java_lang_reflect_Array_setShort;
 		Java_java_lang_reflect_Executable_getParameters0;
+		Java_java_lang_reflect_Executable_getTypeAnnotationBytes0;
+		Java_java_lang_reflect_Field_getTypeAnnotationBytes0;
 		Java_java_lang_Runtime_freeMemory;
                 Java_java_lang_Runtime_maxMemory;
 		Java_java_lang_Runtime_gc;
--- a/makefiles/profile-includes.txt	Tue Oct 08 14:53:14 2013 -0700
+++ b/makefiles/profile-includes.txt	Tue Oct 08 14:57:32 2013 -0700
@@ -107,14 +107,14 @@
     rmid$(EXE_SUFFIX) \
     rmiregistry$(EXE_SUFFIX)
 
-PROFILE_2_JRE_LIB_FILES := 
+PROFILE_2_JRE_LIB_FILES :=
 
-PROFILE_2_JRE_OTHER_FILES := 
+PROFILE_2_JRE_OTHER_FILES :=
 
-PROFILE_2_JRE_JAR_FILES := 
+PROFILE_2_JRE_JAR_FILES :=
 
 
-PROFILE_3_JRE_BIN_FILES := 
+PROFILE_3_JRE_BIN_FILES :=
 
 PROFILE_3_JRE_LIB_FILES := \
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)hprof$(SHARED_LIBRARY_SUFFIX) \
@@ -138,7 +138,7 @@
     management/management.properties \
     management/snmp.acl.template
 
-PROFILE_3_JRE_OTHER_FILES := 
+PROFILE_3_JRE_OTHER_FILES :=
 
 PROFILE_3_JRE_JAR_FILES := \
     management-agent.jar
@@ -171,7 +171,6 @@
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)splashscreen$(SHARED_LIBRARY_SUFFIX) \
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \
-    alt-rt.jar \
     charsets.jar \
     cmm/CIEXYZ.pf \
     cmm/GRAY.pf \
@@ -248,7 +247,6 @@
     man/man1/unpack200.1
 
 FULL_JRE_JAR_FILES := \
-    alt-rt.jar \
     charsets.jar \
     ext/cldrdata.jar \
     ext/dnsns.jar \
--- a/src/macosx/classes/apple/security/AppleProvider.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/macosx/classes/apple/security/AppleProvider.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -43,7 +43,7 @@
 
     public AppleProvider() {
         /* We are the Apple provider */
-        super("Apple", 1.1, info);
+        super("Apple", 1.8d, info);
 
         AccessController.<Object>doPrivileged(new java.security.PrivilegedAction<Object>() {
             public Object run() {
--- a/src/share/classes/com/sun/crypto/provider/SunJCE.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/com/sun/crypto/provider/SunJCE.java	Tue Oct 08 14:57:32 2013 -0700
@@ -104,7 +104,7 @@
 
     public SunJCE() {
         /* We are the "SunJCE" provider */
-        super("SunJCE", 1.7d, info);
+        super("SunJCE", 1.8d, info);
 
         final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" +
             "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
--- a/src/share/classes/com/sun/java/util/jar/pack/Driver.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/Driver.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -303,7 +303,7 @@
                 } else {
                     if (!packfile.toLowerCase().endsWith(".pack") &&
                             !packfile.toLowerCase().endsWith(".pac")) {
-                        System.err.println(MessageFormat.format(RESOURCE.getString(DriverResource.WIRTE_PACKGZ_FILE),packfile));
+                        System.err.println(MessageFormat.format(RESOURCE.getString(DriverResource.WRITE_PACKGZ_FILE),packfile));
                         printUsage(doPack, false, System.err);
                         System.exit(2);
                     }
--- a/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 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
@@ -22,110 +22,99 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package com.sun.java.util.jar.pack;
 
 import java.util.ListResourceBundle;
 
 public class DriverResource extends ListResourceBundle {
-        public static final String VERSION ="VERSION";
-        public static final String BAD_ARGUMENT ="BAD_ARGUMENT";
-        public static final String BAD_OPTION ="BAD_OPTION";
-        public static final String BAD_REPACK_OUTPUT="BAD_REPACK_OUTPUT";
-        public static final String DETECTED_ZIP_COMMENT="DETECTED_ZIP_COMMENT";
-        public static final String SKIP_FOR_REPACKED ="SKIP_FOR_REPACKED";
-        public static final String WRITE_PACK_FILE ="WRITE_PACK_FILE";
-        public static final String WIRTE_PACKGZ_FILE="WIRTE_PACKGZ_FILE";
-        public static final String SKIP_FOR_MOVE_FAILED="SKIP_FOR_MOVE_FAILED";
-        public static final String PACK_HELP="PACK_HELP";
-        public static final String UNPACK_HELP ="UNPACK_HELP";
-        public static final String MORE_INFO = "MORE_INFO";
-        public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION";
-        public static final String BAD_SPEC = "BAD_SPEC";
 
-        //The following string is duplicate in PACK and UNPACK comment,which was draw out to ruduce translation work.
-        private static final String PARAMETER_V = "  -v, --verbose                   increase program verbosity";
-        private static final String PARAMETER_Q = "  -q, --quiet                     set verbosity to lowest level";
-        private static final String PARAMETER_LF = "  -l{F}, --log-file={F}           output to the given log file, or '-' for System.out";
-        private static final String PARAMETER_H = "  -?, -h, --help                  print this message";
-        private static final String PARAMETER_VER = "  -V, --version                   print program version";
-        private static final String PARAMETER_J = "  -J{X}                           pass option X to underlying Java VM";
-
+    public static final String VERSION = "VERSION";
+    public static final String BAD_ARGUMENT = "BAD_ARGUMENT";
+    public static final String BAD_OPTION = "BAD_OPTION";
+    public static final String BAD_REPACK_OUTPUT = "BAD_REPACK_OUTPUT";
+    public static final String DETECTED_ZIP_COMMENT = "DETECTED_ZIP_COMMENT";
+    public static final String SKIP_FOR_REPACKED = "SKIP_FOR_REPACKED";
+    public static final String WRITE_PACK_FILE = "WRITE_PACK_FILE";
+    public static final String WRITE_PACKGZ_FILE = "WRITE_PACKGZ_FILE";
+    public static final String SKIP_FOR_MOVE_FAILED = "SKIP_FOR_MOVE_FAILED";
+    public static final String PACK_HELP = "PACK_HELP";
+    public static final String UNPACK_HELP = "UNPACK_HELP";
+    public static final String MORE_INFO = "MORE_INFO";
+    public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION";
+    public static final String BAD_SPEC = "BAD_SPEC";
 
-        //The following are outputs of command 'pack200' and 'unpack200'.
-        //Don't translate command arguments ,words with a prefix of '-' or '--'.
-        //
-        private static final Object[][] resource= {
-                {VERSION,"{0} version {1}"},//parameter 0:class name;parameter 1: version value
-                {BAD_ARGUMENT,"Bad argument: {0}"},
-                {BAD_OPTION,"Bad option: {0}={1}"},//parameter 0:option name;parameter 1:option value
-                {BAD_REPACK_OUTPUT,"Bad --repack output: {0}"},//parameter 0:filename
-                {DETECTED_ZIP_COMMENT,"Detected ZIP comment: {0}"},//parameter 0:comment
-                {SKIP_FOR_REPACKED,"Skipping because already repacked: {0}"},//parameter 0:filename
-                {WRITE_PACK_FILE,"To write a *.pack file, specify --no-gzip: {0}"},//parameter 0:filename
-                {WIRTE_PACKGZ_FILE,"To write a *.pack.gz file, specify --gzip: {0}"},//parameter 0:filename
-                {SKIP_FOR_MOVE_FAILED,"Skipping unpack because move failed: {0}"},//parameter 0:filename
-                {PACK_HELP,new String[]{
-                                "Usage:  pack200 [-opt... | --option=value]... x.pack[.gz] y.jar",
-                                "",
-                                "Packing Options",
-                                "  -g, --no-gzip                   output a plain *.pack file with no zipping",
-                                "  --gzip                          (default) post-process the pack output with gzip",
-                                "  -G, --strip-debug               remove debugging attributes while packing",
-                                "  -O, --no-keep-file-order        do not transmit file ordering information",
-                                "  --keep-file-order               (default) preserve input file ordering",
-                                "  -S{N}, --segment-limit={N}      output segment limit (default N=1Mb)",
-                                "  -E{N}, --effort={N}             packing effort (default N=5)",
-                                "  -H{h}, --deflate-hint={h}       transmit deflate hint: true, false, or keep (default)",
-                                "  -m{V}, --modification-time={V}  transmit modtimes: latest or keep (default)",
-                                "  -P{F}, --pass-file={F}          transmit the given input element(s) uncompressed",
-                                "  -U{a}, --unknown-attribute={a}  unknown attribute action: error, strip, or pass (default)",
-                                "  -C{N}={L}, --class-attribute={N}={L}  (user-defined attribute)",
-                                "  -F{N}={L}, --field-attribute={N}={L}  (user-defined attribute)",
-                                "  -M{N}={L}, --method-attribute={N}={L} (user-defined attribute)",
-                                "  -D{N}={L}, --code-attribute={N}={L}   (user-defined attribute)",
-                                "  -f{F}, --config-file={F}        read file F for Pack200.Packer properties",
-                                PARAMETER_V ,
-                                PARAMETER_Q ,
-                                PARAMETER_LF ,
-                                PARAMETER_H ,
-                                PARAMETER_VER ,
-                                PARAMETER_J,
-                                "",
-                                "Notes:",
-                                "  The -P, -C, -F, -M, and -D options accumulate.",
-                                "  Example attribute definition:  -C SourceFile=RUH .",
-                                "  Config. file properties are defined by the Pack200 API.",
-                                "  For meaning of -S, -E, -H-, -m, -U values, see Pack200 API.",
-                                "  Layout definitions (like RUH) are defined by JSR 200.",
-                                "",
-                                "Repacking mode updates the JAR file with a pack/unpack cycle:",
-                                "    pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n"
-                                }
-                },
-                {UNPACK_HELP,new String[]{
-                                "Usage:  unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n",
-                                "",
-                                "Unpacking Options",
-                                "  -H{h}, --deflate-hint={h}     override transmitted deflate hint: true, false, or keep (default)",
-                                "  -r, --remove-pack-file        remove input file after unpacking",
-                                PARAMETER_V ,
-                                PARAMETER_Q ,
-                                PARAMETER_LF ,
-                                PARAMETER_H ,
-                                PARAMETER_VER ,
-                                PARAMETER_J,
-                            }
-                },
+    /*
+     * The following are the output of 'pack200' and 'unpack200' commands.
+     * Do not translate command arguments and words with a prefix of '-' or '--'.
+     */
+    private static final Object[][] resource = {
+        {VERSION, "{0} version {1}"}, // parameter 0:class name;parameter 1: version value
+        {BAD_ARGUMENT, "Bad argument: {0}"},
+        {BAD_OPTION, "Bad option: {0}={1}"}, // parameter 0:option name;parameter 1:option value
+        {BAD_REPACK_OUTPUT, "Bad --repack output: {0}"}, // parameter 0:filename
+        {DETECTED_ZIP_COMMENT, "Detected ZIP comment: {0}"}, // parameter 0:comment
+        {SKIP_FOR_REPACKED, "Skipping because already repacked: {0}"}, // parameter 0:filename
+        {WRITE_PACK_FILE, "To write a *.pack file, specify --no-gzip: {0}"}, // parameter 0:filename
+        {WRITE_PACKGZ_FILE, "To write a *.pack.gz file, specify --gzip: {0}"}, // parameter 0:filename
+        {SKIP_FOR_MOVE_FAILED, "Skipping unpack because move failed: {0}"}, // parameter 0:filename
+        {PACK_HELP, new String[] {
+                "Usage:  pack200 [-opt... | --option=value]... x.pack[.gz] y.jar",
+                "",
+                "Packing Options",
+                "  -g, --no-gzip                   output a plain *.pack file with no zipping",
+                "  --gzip                          (default) post-process the pack output with gzip",
+                "  -G, --strip-debug               remove debugging attributes while packing",
+                "  -O, --no-keep-file-order        do not transmit file ordering information",
+                "  --keep-file-order               (default) preserve input file ordering",
+                "  -S{N}, --segment-limit={N}      output segment limit (default N=1Mb)",
+                "  -E{N}, --effort={N}             packing effort (default N=5)",
+                "  -H{h}, --deflate-hint={h}       transmit deflate hint: true, false, or keep (default)",
+                "  -m{V}, --modification-time={V}  transmit modtimes: latest or keep (default)",
+                "  -P{F}, --pass-file={F}          transmit the given input element(s) uncompressed",
+                "  -U{a}, --unknown-attribute={a}  unknown attribute action: error, strip, or pass (default)",
+                "  -C{N}={L}, --class-attribute={N}={L}  (user-defined attribute)",
+                "  -F{N}={L}, --field-attribute={N}={L}  (user-defined attribute)",
+                "  -M{N}={L}, --method-attribute={N}={L} (user-defined attribute)",
+                "  -D{N}={L}, --code-attribute={N}={L}   (user-defined attribute)",
+                "  -f{F}, --config-file={F}        read file F for Pack200.Packer properties",
+                "  -v, --verbose                   increase program verbosity",
+                "  -q, --quiet                     set verbosity to lowest level",
+                "  -l{F}, --log-file={F}           output to the given log file, or '-' for System.out",
+                "  -?, -h, --help                  print this message",
+                "  -V, --version                   print program version",
+                "  -J{X}                           pass option X to underlying Java VM",
+                "",
+                "Notes:",
+                "  The -P, -C, -F, -M, and -D options accumulate.",
+                "  Example attribute definition:  -C SourceFile=RUH .",
+                "  Config. file properties are defined by the Pack200 API.",
+                "  For meaning of -S, -E, -H-, -m, -U values, see Pack200 API.",
+                "  Layout definitions (like RUH) are defined by JSR 200.",
+                "",
+                "Repacking mode updates the JAR file with a pack/unpack cycle:",
+                "    pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n"
+            }
+        },
+        {UNPACK_HELP, new String[] {
+                "Usage:  unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n",
+                "",
+                "Unpacking Options",
+                "  -H{h}, --deflate-hint={h}     override transmitted deflate hint: true, false, or keep (default)",
+                "  -r, --remove-pack-file        remove input file after unpacking",
+                "  -v, --verbose                 increase program verbosity",
+                "  -q, --quiet                   set verbosity to lowest level",
+                "  -l{F}, --log-file={F}         output to the given log file, or '-' for System.out",
+                "  -?, -h, --help                print this message",
+                "  -V, --version                 print program version",
+                "  -J{X}                         pass option X to underlying Java VM"
+            }
+        },
+        {MORE_INFO, "(For more information, run {0} --help .)"}, // parameter 0:command name
+        {DUPLICATE_OPTION, "duplicate option: {0}"}, // parameter 0:option
+        {BAD_SPEC, "bad spec for {0}: {1}"}, // parameter 0:option;parameter 1:specifier
+    };
 
-                {MORE_INFO,"(For more information, run {0} --help .)"},//parameter 0:command name
-                {DUPLICATE_OPTION,"duplicate option: {0}"},//parameter 0:option
-                {BAD_SPEC,"bad spec for {0}: {1}"},//parameter 0:option;parameter 1:specifier
-        };
-
-        protected Object[][] getContents() {
-                return resource;
-        }
-
-
+    protected Object[][] getContents() {
+        return resource;
+    }
 }
--- a/src/share/classes/com/sun/security/sasl/Provider.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/com/sun/security/sasl/Provider.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -53,7 +53,7 @@
         " server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)";
 
     public Provider() {
-        super("SunSASL", 1.7d, info);
+        super("SunSASL", 1.8d, info);
 
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
             public Void run() {
--- a/src/share/classes/java/io/File.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/io/File.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1908,10 +1908,18 @@
             } else {
                 n = Math.abs(n);
             }
+
+            // Use only the file name from the supplied prefix
+            prefix = (new File(prefix)).getName();
+
             String name = prefix + Long.toString(n) + suffix;
             File f = new File(dir, name);
-            if (!name.equals(f.getName()) || f.isInvalid())
-                throw new IOException("Unable to create temporary file");
+            if (!name.equals(f.getName()) || f.isInvalid()) {
+                if (System.getSecurityManager() != null)
+                    throw new IOException("Unable to create temporary file");
+                else
+                    throw new IOException("Unable to create temporary file, " + f);
+            }
             return f;
         }
     }
--- a/src/share/classes/java/lang/Class.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/Class.java	Tue Oct 08 14:57:32 2013 -0700
@@ -3414,16 +3414,20 @@
     transient ClassValue.ClassValueMap classValueMap;
 
     /**
-     * Returns an AnnotatedType object that represents the use of a type to specify
-     * the superclass of the entity represented by this Class. (The <em>use</em> of type
-     * Foo to specify the superclass in '... extends Foo' is distinct from the
-     * <em>declaration</em> of type Foo.)
+     * Returns an {@code AnnotatedType} object that represents the use of a
+     * type to specify the superclass of the entity represented by this {@code
+     * Class} object. (The <em>use</em> of type Foo to specify the superclass
+     * in '...  extends Foo' is distinct from the <em>declaration</em> of type
+     * Foo.)
      *
-     * If this Class represents a class type whose declaration does not explicitly
-     * indicate an annotated superclass, the return value is null.
+     * <p> If this {@code Class} object represents a type whose declaration
+     * does not explicitly indicate an annotated superclass, then the return
+     * value is an {@code AnnotatedType} object representing an element with no
+     * annotations.
      *
-     * If this Class represents either the Object class, an interface type, an
-     * array type, a primitive type, or void, the return value is null.
+     * <p> If this {@code Class} represents either the {@code Object} class, an
+     * interface type, an array type, a primitive type, or void, the return
+     * value is {@code null}.
      *
      * @return an object representing the superclass
      * @since 1.8
@@ -3441,30 +3445,33 @@
     }
 
     /**
-     * Returns an array of AnnotatedType objects that represent the use of types to
-     * specify superinterfaces of the entity represented by this Class. (The <em>use</em>
-     * of type Foo to specify a superinterface in '... implements Foo' is
-     * distinct from the <em>declaration</em> of type Foo.)
+     * Returns an array of {@code AnnotatedType} objects that represent the use
+     * of types to specify superinterfaces of the entity represented by this
+     * {@code Class} object. (The <em>use</em> of type Foo to specify a
+     * superinterface in '... implements Foo' is distinct from the
+     * <em>declaration</em> of type Foo.)
      *
-     * If this Class represents a class, the return value is an array
-     * containing objects representing the uses of interface types to specify
-     * interfaces implemented by the class. The order of the objects in the
-     * array corresponds to the order of the interface types used in the
-     * 'implements' clause of the declaration of this Class.
+     * <p> If this {@code Class} object represents a class, the return value is
+     * an array containing objects representing the uses of interface types to
+     * specify interfaces implemented by the class. The order of the objects in
+     * the array corresponds to the order of the interface types used in the
+     * 'implements' clause of the declaration of this {@code Class} object.
      *
-     * If this Class represents an interface, the return value is an array
-     * containing objects representing the uses of interface types to specify
-     * interfaces directly extended by the interface. The order of the objects in
-     * the array corresponds to the order of the interface types used in the
-     * 'extends' clause of the declaration of this Class.
+     * <p> If this {@code Class} object represents an interface, the return
+     * value is an array containing objects representing the uses of interface
+     * types to specify interfaces directly extended by the interface. The
+     * order of the objects in the array corresponds to the order of the
+     * interface types used in the 'extends' clause of the declaration of this
+     * {@code Class} object.
      *
-     * If this Class represents a class or interface whose declaration does not
-     * explicitly indicate any annotated superinterfaces, the return value is an
+     * <p> If this {@code Class} object represents a class or interface whose
+     * declaration does not explicitly indicate any annotated superinterfaces,
+     * the return value is an array of length 0.
+     *
+     * <p> If this {@code Class} object represents either the {@code Object}
+     * class, an array type, a primitive type, or void, the return value is an
      * array of length 0.
      *
-     * If this Class represents either the Object class, an array type, a
-     * primitive type, or void, the return value is an array of length 0.
-     *
      * @return an array representing the superinterfaces
      * @since 1.8
      */
--- a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Tue Oct 08 14:57:32 2013 -0700
@@ -125,10 +125,7 @@
 
         this.implMethod = implMethod;
         this.implInfo = caller.revealDirect(implMethod);
-        // @@@ Temporary work-around pending resolution of 8005119
-        this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial)
-                        ? MethodHandleInfo.REF_invokeVirtual
-                        : implInfo.getReferenceKind();
+        this.implKind = implInfo.getReferenceKind();
         this.implIsInstanceMethod =
                 implKind == MethodHandleInfo.REF_invokeVirtual ||
                 implKind == MethodHandleInfo.REF_invokeSpecial ||
--- a/src/share/classes/java/lang/invoke/BoundMethodHandle.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/BoundMethodHandle.java	Tue Oct 08 14:57:32 2013 -0700
@@ -360,6 +360,10 @@
             return new Name(mh, mhName);
         }
 
+        NamedFunction getterFunction(int i) {
+            return new NamedFunction(getters[i]);
+        }
+
         static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
 
         private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
@@ -394,6 +398,7 @@
         private boolean isPlaceholder() { return clazz == null; }
 
         private static final HashMap<String, SpeciesData> CACHE = new HashMap<>();
+        static { CACHE.put("", EMPTY); }  // make bootstrap predictable
         private static final boolean INIT_DONE;  // set after <clinit> finishes...
 
         SpeciesData extendWithType(char type) {
@@ -524,18 +529,18 @@
          * A concrete BMH species adheres to the following schema:
          *
          * <pre>
-         * class Species_<<types>> extends BoundMethodHandle {
-         *     <<fields>>
-         *     final SpeciesData speciesData() { return SpeciesData.get("<<types>>"); }
+         * class Species_[[types]] extends BoundMethodHandle {
+         *     [[fields]]
+         *     final SpeciesData speciesData() { return SpeciesData.get("[[types]]"); }
          * }
          * </pre>
          *
-         * The {@code <<types>>} signature is precisely the string that is passed to this
+         * The {@code [[types]]} signature is precisely the string that is passed to this
          * method.
          *
-         * The {@code <<fields>>} section consists of one field definition per character in
+         * The {@code [[fields]]} section consists of one field definition per character in
          * the type signature, adhering to the naming schema described in the definition of
-         * {@link #makeFieldName()}.
+         * {@link #makeFieldName}.
          *
          * For example, a concrete BMH species for two reference and one integral bound values
          * would have the following shape:
@@ -817,7 +822,7 @@
          * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
          * {@link MethodHandle#linkToSpecial}.
          *
-         * The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void}
+         * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void}
          * result of the {@code <init>} invocation. This entry is replaced.
          */
         private static MethodHandle linkConstructor(MethodHandle cmh) {
--- a/src/share/classes/java/lang/invoke/CallSite.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/CallSite.java	Tue Oct 08 14:57:32 2013 -0700
@@ -60,7 +60,7 @@
  * <p>
  * Here is a sample use of call sites and bootstrap methods which links every
  * dynamic call site to print its arguments:
-<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
+<blockquote><pre>{@code
 static void test() throws Throwable {
     // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
     InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
@@ -79,7 +79,7 @@
   // ignore caller and name, but match the type:
   return new ConstantCallSite(printArgs.asType(type));
 }
-</pre></blockquote>
+}</pre></blockquote>
  * @author John Rose, JSR 292 EG
  */
 abstract
@@ -199,12 +199,12 @@
      * which has been linked to this call site.
      * <p>
      * This method is equivalent to the following code:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * MethodHandle getTarget, invoker, result;
      * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
      * invoker = MethodHandles.exactInvoker(this.type());
      * result = MethodHandles.foldArguments(invoker, getTarget)
-     * </pre></blockquote>
+     * }</pre></blockquote>
      *
      * @return a method handle which always invokes this call site's current target
      */
@@ -261,7 +261,7 @@
                              Object info,
                              // Caller information:
                              Class<?> callerClass) {
-        Object caller = IMPL_LOOKUP.in(callerClass);
+        MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass);
         CallSite site;
         try {
             Object binding;
@@ -273,14 +273,44 @@
             } else {
                 Object[] argv = (Object[]) info;
                 maybeReBoxElements(argv);
-                if (3 + argv.length > 255)
-                    throw new BootstrapMethodError("too many bootstrap method arguments");
-                MethodType bsmType = bootstrapMethod.type();
-                if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
-                    binding = bootstrapMethod.invoke(caller, name, type, argv);
-                else
-                    binding = MethodHandles.spreadInvoker(bsmType, 3)
-                        .invoke(bootstrapMethod, caller, name, type, argv);
+                switch (argv.length) {
+                case 0:
+                    binding = bootstrapMethod.invoke(caller, name, type);
+                    break;
+                case 1:
+                    binding = bootstrapMethod.invoke(caller, name, type,
+                                                     argv[0]);
+                    break;
+                case 2:
+                    binding = bootstrapMethod.invoke(caller, name, type,
+                                                     argv[0], argv[1]);
+                    break;
+                case 3:
+                    binding = bootstrapMethod.invoke(caller, name, type,
+                                                     argv[0], argv[1], argv[2]);
+                    break;
+                case 4:
+                    binding = bootstrapMethod.invoke(caller, name, type,
+                                                     argv[0], argv[1], argv[2], argv[3]);
+                    break;
+                case 5:
+                    binding = bootstrapMethod.invoke(caller, name, type,
+                                                     argv[0], argv[1], argv[2], argv[3], argv[4]);
+                    break;
+                case 6:
+                    binding = bootstrapMethod.invoke(caller, name, type,
+                                                     argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+                    break;
+                default:
+                    final int NON_SPREAD_ARG_COUNT = 3;  // (caller, name, type)
+                    if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
+                        throw new BootstrapMethodError("too many bootstrap method arguments");
+                    MethodType bsmType = bootstrapMethod.type();
+                    MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
+                    MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
+                    MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+                    binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv);
+                }
             }
             //System.out.println("BSM for "+name+type+" => "+binding);
             if (binding instanceof CallSite) {
--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java	Tue Oct 08 14:57:32 2013 -0700
@@ -257,12 +257,12 @@
         assert(names.length == nameCursor);
         if (doesAlloc) {
             // names = { argx,y,z,... new C, init method }
-            names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
-            names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
+            names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
+            names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
         } else if (needsInit) {
-            names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
+            names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
         } else {
-            names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]);
+            names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
         }
         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
         assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
@@ -637,18 +637,18 @@
         final int RESULT    = nameCursor-1;  // either the call or the cast
         Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
         if (needsInit)
-            names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
+            names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]);
         if (needsCast && !isGetter)
-            names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
+            names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
         Object[] outArgs = new Object[1 + linkerType.parameterCount()];
         assert(outArgs.length == (isGetter ? 3 : 4));
         outArgs[0] = UNSAFE;
         if (isStatic) {
-            outArgs[1] = names[F_HOLDER]  = new Name(NF_staticBase, names[DMH_THIS]);
-            outArgs[2] = names[F_OFFSET]  = new Name(NF_staticOffset, names[DMH_THIS]);
+            outArgs[1] = names[F_HOLDER]  = new Name(Lazy.NF_staticBase, names[DMH_THIS]);
+            outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_staticOffset, names[DMH_THIS]);
         } else {
-            outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
-            outArgs[2] = names[F_OFFSET]  = new Name(NF_fieldOffset, names[DMH_THIS]);
+            outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]);
+            outArgs[2] = names[F_OFFSET]  = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]);
         }
         if (!isGetter) {
             outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
@@ -656,7 +656,7 @@
         for (Object a : outArgs)  assert(a != null);
         names[LINKER_CALL] = new Name(linker, outArgs);
         if (needsCast && isGetter)
-            names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
+            names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
         for (Name n : names)  assert(n != null);
         String fieldOrStatic = (isStatic ? "Static" : "Field");
         String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
@@ -665,48 +665,54 @@
         return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
     }
 
-    private static final NamedFunction
-            NF_internalMemberName,
-            NF_internalMemberNameEnsureInit,
-            NF_ensureInitialized,
-            NF_fieldOffset,
-            NF_checkBase,
-            NF_staticBase,
-            NF_staticOffset,
-            NF_checkCast,
-            NF_allocateInstance,
-            NF_constructorMethod;
-    static {
-        try {
-            NamedFunction nfs[] = {
-                NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("internalMemberName", Object.class)),
-                NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
-                NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("ensureInitialized", Object.class)),
-                NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("fieldOffset", Object.class)),
-                NF_checkBase = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("checkBase", Object.class)),
-                NF_staticBase = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("staticBase", Object.class)),
-                NF_staticOffset = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("staticOffset", Object.class)),
-                NF_checkCast = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("checkCast", Object.class, Object.class)),
-                NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("allocateInstance", Object.class)),
-                NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
-                    .getDeclaredMethod("constructorMethod", Object.class))
-            };
-            for (NamedFunction nf : nfs) {
-                // Each nf must be statically invocable or we get tied up in our bootstraps.
-                assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
-                nf.resolve();
+    /**
+     * Pre-initialized NamedFunctions for bootstrapping purposes.
+     * Factored in an inner class to delay initialization until first usage.
+     */
+    private static class Lazy {
+        static final NamedFunction
+                NF_internalMemberName,
+                NF_internalMemberNameEnsureInit,
+                NF_ensureInitialized,
+                NF_fieldOffset,
+                NF_checkBase,
+                NF_staticBase,
+                NF_staticOffset,
+                NF_checkCast,
+                NF_allocateInstance,
+                NF_constructorMethod;
+        static {
+            try {
+                NamedFunction nfs[] = {
+                        NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("internalMemberName", Object.class)),
+                        NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
+                        NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("ensureInitialized", Object.class)),
+                        NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("fieldOffset", Object.class)),
+                        NF_checkBase = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("checkBase", Object.class)),
+                        NF_staticBase = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("staticBase", Object.class)),
+                        NF_staticOffset = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("staticOffset", Object.class)),
+                        NF_checkCast = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("checkCast", Object.class, Object.class)),
+                        NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("allocateInstance", Object.class)),
+                        NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
+                                .getDeclaredMethod("constructorMethod", Object.class))
+                };
+                for (NamedFunction nf : nfs) {
+                    // Each nf must be statically invocable or we get tied up in our bootstraps.
+                    assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
+                    nf.resolve();
+                }
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError(ex);
             }
-        } catch (ReflectiveOperationException ex) {
-            throw newInternalError(ex);
         }
     }
 }
--- a/src/share/classes/java/lang/invoke/InvokeGeneric.java	Tue Oct 08 14:53:14 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2009, 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 java.lang.invoke;
-
-import sun.invoke.util.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * Adapters which manage inexact MethodHandle.invoke calls.
- * The JVM calls one of these when the exact type match fails.
- * @author jrose
- */
-class InvokeGeneric {
-    // erased type for the call, which originates from an inexact invoke site
-    private final MethodType erasedCallerType;
-    // an invoker of type (MT, MH; A...) -> R
-    private final MethodHandle initialInvoker;
-
-    /** Compute and cache information for this adapter, so that it can
-     *  call out to targets of the erasure-family of the given erased type.
-     */
-    /*non-public*/ InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException {
-        assert(erasedCallerType.equals(erasedCallerType.erase()));
-        this.erasedCallerType = erasedCallerType;
-        this.initialInvoker = makeInitialInvoker();
-        assert initialInvoker.type().equals(erasedCallerType
-                                            .insertParameterTypes(0, MethodType.class, MethodHandle.class))
-            : initialInvoker.type();
-    }
-
-    private static MethodHandles.Lookup lookup() {
-        return IMPL_LOOKUP;
-    }
-
-    /** Return the adapter information for this type's erasure. */
-    /*non-public*/ static MethodHandle generalInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException {
-        InvokeGeneric gen = new InvokeGeneric(erasedCallerType);
-        return gen.initialInvoker;
-    }
-
-    private MethodHandle makeInitialInvoker() throws ReflectiveOperationException {
-        // postDispatch = #(MH'; MT, MH; A...){MH'(MT, MH; A)}
-        MethodHandle postDispatch = makePostDispatchInvoker();
-        MethodHandle invoker;
-        if (returnConversionPossible()) {
-            invoker = MethodHandles.foldArguments(postDispatch,
-                                                  dispatcher("dispatchWithConversion"));
-        } else {
-            invoker = MethodHandles.foldArguments(postDispatch, dispatcher("dispatch"));
-        }
-        return invoker;
-    }
-
-    private static final Class<?>[] EXTRA_ARGS = { MethodType.class, MethodHandle.class };
-    private MethodHandle makePostDispatchInvoker() {
-        // Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...).
-        MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS);
-        return invokerType.invokers().exactInvoker();
-    }
-    private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) {
-        assert(targetInvoker.type().parameterType(0) == MethodHandle.class);
-        return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS);
-    }
-
-    private MethodHandle dispatcher(String dispatchName) throws ReflectiveOperationException {
-        return lookup().bind(this, dispatchName,
-                             MethodType.methodType(MethodHandle.class,
-                                                   MethodType.class, MethodHandle.class));
-    }
-
-    static final boolean USE_AS_TYPE_PATH = true;
-
-    /** Return a method handle to invoke on the callerType, target, and remaining arguments.
-     *  The method handle must finish the call.
-     *  This is the first look at the caller type and target.
-     */
-    private MethodHandle dispatch(MethodType callerType, MethodHandle target) {
-        MethodType targetType = target.type();
-        if (USE_AS_TYPE_PATH || target.isVarargsCollector()) {
-            MethodHandle newTarget = target.asType(callerType);
-            targetType = callerType;
-            Invokers invokers = targetType.invokers();
-            MethodHandle invoker = invokers.erasedInvokerWithDrops;
-            if (invoker == null) {
-                invokers.erasedInvokerWithDrops = invoker =
-                    dropDispatchArguments(invokers.erasedInvoker());
-            }
-            return invoker.bindTo(newTarget);
-        }
-        throw new RuntimeException("NYI");
-    }
-
-    private MethodHandle dispatchWithConversion(MethodType callerType, MethodHandle target) {
-        MethodHandle finisher = dispatch(callerType, target);
-        if (returnConversionNeeded(callerType, target))
-            finisher = addReturnConversion(finisher, callerType.returnType());  //FIXME: slow
-        return finisher;
-    }
-
-    private boolean returnConversionPossible() {
-        Class<?> needType = erasedCallerType.returnType();
-        return !needType.isPrimitive();
-    }
-    private boolean returnConversionNeeded(MethodType callerType, MethodHandle target) {
-        Class<?> needType = callerType.returnType();
-        if (needType == erasedCallerType.returnType())
-            return false;  // no conversions possible, since must be primitive or Object
-        Class<?> haveType = target.type().returnType();
-        if (VerifyType.isNullConversion(haveType, needType) && !needType.isInterface())
-            return false;
-        return true;
-    }
-    private MethodHandle addReturnConversion(MethodHandle finisher, Class<?> type) {
-        // FIXME: This is slow because it creates a closure node on every call that requires a return cast.
-        MethodType finisherType = finisher.type();
-        MethodHandle caster = ValueConversions.identity(type);
-        caster = caster.asType(caster.type().changeParameterType(0, finisherType.returnType()));
-        finisher = MethodHandles.filterReturnValue(finisher, caster);
-        return finisher.asType(finisherType);
-    }
-
-    public String toString() {
-        return "InvokeGeneric"+erasedCallerType;
-    }
-}
--- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java	Tue Oct 08 14:57:32 2013 -0700
@@ -242,9 +242,6 @@
 
     /**
      * Extract the MemberName of a newly-defined method.
-     *
-     * @param classFile
-     * @return
      */
     private MemberName loadMethod(byte[] classFile) {
         Class<?> invokerClass = loadAndInitializeInvokerClass(classFile, cpPatches(classFile));
@@ -253,10 +250,6 @@
 
     /**
      * Define a given class as anonymous class in the runtime system.
-     *
-     * @param classBytes
-     * @param patches
-     * @return
      */
     private static Class<?> loadAndInitializeInvokerClass(byte[] classBytes, Object[] patches) {
         Class<?> invokerClass = UNSAFE.defineAnonymousClass(HOST_CLASS, classBytes, patches);
@@ -264,14 +257,6 @@
         return invokerClass;
     }
 
-    /**
-     * TODO
-     *
-     * @param invokerClass
-     * @param name
-     * @param type
-     * @return
-     */
     private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) {
         MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic);
         //System.out.println("resolveInvokerMember => "+member);
@@ -499,10 +484,6 @@
 
     /**
      * Generate customized bytecode for a given LambdaForm.
-     *
-     * @param form
-     * @param invokerType
-     * @return
      */
     static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {
         InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
@@ -565,8 +546,6 @@
 
     /**
      * Emit an invoke for the given name.
-     *
-     * @param name
      */
     void emitInvoke(Name name) {
         if (true) {
@@ -645,8 +624,6 @@
 
     /**
      * Emit an invoke for the given name, using the MemberName directly.
-     *
-     * @param name
      */
     void emitStaticInvoke(MemberName member, Name name) {
         assert(member.equals(name.function.member()));
@@ -690,9 +667,6 @@
 
     /**
      * Check if MemberName is a call to MethodHandleImpl.selectAlternative.
-     *
-     * @param member
-     * @return true if member is a call to MethodHandleImpl.selectAlternative
      */
     private boolean isSelectAlternative(MemberName member) {
         return member != null &&
@@ -704,14 +678,12 @@
      * Emit bytecode for the selectAlternative idiom.
      *
      * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
-     *
+     * <blockquote><pre>{@code
      *   Lambda(a0:L,a1:I)=>{
      *     t2:I=foo.test(a1:I);
      *     t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
      *     t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
-     *
-     * @param selectAlternativeName
-     * @param invokeBasicName
+     * }</pre></blockquote>
      */
     private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
         MethodType type = selectAlternativeName.function.methodType();
@@ -750,11 +722,6 @@
         mv.visitLabel(L_done);
     }
 
-    /**
-     *
-     * @param name
-     * @param paramIndex
-     */
     private void emitPushArgument(Name name, int paramIndex) {
         Object arg = name.arguments[paramIndex];
         char ptype = name.function.parameterType(paramIndex);
@@ -923,9 +890,6 @@
 
     /**
      * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments.
-     *
-     * @param sig
-     * @return
      */
     static MemberName generateLambdaFormInterpreterEntryPoint(String sig) {
         assert(LambdaForm.isValidSignature(sig));
@@ -993,10 +957,6 @@
 
     /**
      * Generate bytecode for a NamedFunction invoker.
-     *
-     * @param srcType
-     * @param dstType
-     * @return
      */
     static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) {
         MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE;
--- a/src/share/classes/java/lang/invoke/Invokers.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/Invokers.java	Tue Oct 08 14:57:32 2013 -0700
@@ -44,6 +44,7 @@
 
     // exact invoker for the outgoing call
     private /*lazy*/ MethodHandle exactInvoker;
+    private /*lazy*/ MethodHandle basicInvoker;  // invokeBasic (unchecked exact)
 
     // erased (partially untyped but with primitives) invoker for the outgoing call
     // FIXME: get rid of
@@ -74,21 +75,7 @@
     /*non-public*/ MethodHandle exactInvoker() {
         MethodHandle invoker = exactInvoker;
         if (invoker != null)  return invoker;
-        MethodType mtype = targetType;
-        MethodType invokerType = mtype.invokerType();
-        LambdaForm lform;
-        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
-        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - MTYPE_ARG_APPENDED) {
-            lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_INVOKER);
-            invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
-        } else {
-            // At maximum arity, we cannot afford an extra mtype argument,
-            // so build a fully customized (non-cached) invoker form.
-            lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER);
-            invoker = SimpleMethodHandle.make(invokerType, lform);
-        }
-        invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invokeExact", mtype));
-        assert(checkInvoker(invoker));
+        invoker = makeExactOrGeneralInvoker(true);
         exactInvoker = invoker;
         return invoker;
     }
@@ -96,43 +83,56 @@
     /*non-public*/ MethodHandle generalInvoker() {
         MethodHandle invoker = generalInvoker;
         if (invoker != null)  return invoker;
-        MethodType mtype = targetType;
-        MethodType invokerType = mtype.invokerType();
-        LambdaForm lform;
-        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
-        assert(GENERIC_INVOKER_SLOP >= MTYPE_ARG_APPENDED);
-        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - GENERIC_INVOKER_SLOP) {
-            prepareForGenericCall(mtype);
-            lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_INVOKER);
-            invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
-        } else {
-            // At maximum arity, we cannot afford an extra mtype argument,
-            // so build a fully customized (non-cached) invoker form.
-            lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER);
-            invoker = SimpleMethodHandle.make(invokerType, lform);
-        }
-        invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invoke", mtype));
-        assert(checkInvoker(invoker));
+        invoker = makeExactOrGeneralInvoker(false);
         generalInvoker = invoker;
         return invoker;
     }
 
-    /*non-public*/ MethodHandle makeBasicInvoker() {
-        MethodHandle invoker = DirectMethodHandle.make(invokeBasicMethod(targetType));
-        assert(targetType == targetType.basicType());
-        // Note:  This is not cached here.  It is cached by the calling MethodTypeForm.
+    private MethodHandle makeExactOrGeneralInvoker(boolean isExact) {
+        MethodType mtype = targetType;
+        MethodType invokerType = mtype.invokerType();
+        int which = (isExact ? MethodTypeForm.LF_EX_INVOKER : MethodTypeForm.LF_GEN_INVOKER);
+        LambdaForm lform = invokeHandleForm(mtype, false, which);
+        MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
+        String whichName = (isExact ? "invokeExact" : "invoke");
+        invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype));
         assert(checkInvoker(invoker));
+        maybeCompileToBytecode(invoker);
         return invoker;
     }
 
-    static MemberName invokeBasicMethod(MethodType type) {
-        type = type.basicType();
-        String name = "invokeBasic";
+    /** If the target type seems to be common enough, eagerly compile the invoker to bytecodes. */
+    private void maybeCompileToBytecode(MethodHandle invoker) {
+        final int EAGER_COMPILE_ARITY_LIMIT = 10;
+        if (targetType == targetType.erase() &&
+            targetType.parameterCount() < EAGER_COMPILE_ARITY_LIMIT) {
+            invoker.form.compileToBytecode();
+        }
+    }
+
+    /*non-public*/ MethodHandle basicInvoker() {
+        MethodHandle invoker = basicInvoker;
+        if (invoker != null)  return invoker;
+        MethodType basicType = targetType.basicType();
+        if (basicType != targetType) {
+            // double cache; not used significantly
+            return basicInvoker = basicType.invokers().basicInvoker();
+        }
+        MemberName method = invokeBasicMethod(basicType);
+        invoker = DirectMethodHandle.make(method);
+        assert(checkInvoker(invoker));
+        basicInvoker = invoker;
+        return invoker;
+    }
+
+    // This next one is called from LambdaForm.NamedFunction.<init>.
+    /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) {
+        assert(basicType == basicType.basicType());
         try {
             //Lookup.findVirtual(MethodHandle.class, name, type);
-            return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, name, type);
+            return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, "invokeBasic", basicType);
         } catch (ReflectiveOperationException ex) {
-            throw newInternalError("JVM cannot find invoker for "+type, ex);
+            throw newInternalError("JVM cannot find invoker for "+basicType, ex);
         }
     }
 
@@ -184,6 +184,7 @@
             vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader);
         }
         assert(vaInvoker.type().equals(spreadInvokerType.invokerType()));
+        maybeCompileToBytecode(vaInvoker);
         spreadInvokers[leadingArgCount] = vaInvoker;
         return vaInvoker;
     }
@@ -231,32 +232,38 @@
         return "Invokers"+targetType;
     }
 
-    static MemberName exactInvokerMethod(MethodType mtype, Object[] appendixResult) {
+    static MemberName methodHandleInvokeLinkerMethod(String name,
+                                                     MethodType mtype,
+                                                     Object[] appendixResult) {
+        int which;
+        switch (name) {
+        case "invokeExact":  which = MethodTypeForm.LF_EX_LINKER; break;
+        case "invoke":       which = MethodTypeForm.LF_GEN_LINKER; break;
+        default:             throw new InternalError("not invoker: "+name);
+        }
         LambdaForm lform;
-        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
-        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MTYPE_ARG_APPENDED) {
-            lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_LINKER);
+        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
+            lform = invokeHandleForm(mtype, false, which);
             appendixResult[0] = mtype;
         } else {
-            lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_LINKER);
+            lform = invokeHandleForm(mtype, true, which);
         }
         return lform.vmentry;
     }
 
-    static MemberName genericInvokerMethod(MethodType mtype, Object[] appendixResult) {
-        LambdaForm lform;
-        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
-        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - (MTYPE_ARG_APPENDED + GENERIC_INVOKER_SLOP)) {
-            lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_LINKER);
-            appendixResult[0] = mtype;
-            prepareForGenericCall(mtype);
-        } else {
-            lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_LINKER);
-        }
-        return lform.vmentry;
-    }
+    // argument count to account for trailing "appendix value" (typically the mtype)
+    private static final int MH_LINKER_ARG_APPENDED = 1;
 
-    private static LambdaForm invokeForm(MethodType mtype, boolean customized, int which) {
+    /** Returns an adapter for invokeExact or generic invoke, as a MH or constant pool linker.
+     * If !customized, caller is responsible for supplying, during adapter execution,
+     * a copy of the exact mtype.  This is because the adapter might be generalized to
+     * a basic type.
+     * @param mtype the caller's method type (either basic or full-custom)
+     * @param customized whether to use a trailing appendix argument (to carry the mtype)
+     * @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker");
+     *                          0x02 whether it is for invokeExact or generic invoke
+     */
+    private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) {
         boolean isCached;
         if (!customized) {
             mtype = mtype.basicType();  // normalize Z to I, String to Object, etc.
@@ -301,41 +308,24 @@
                 : Arrays.asList(mtype, customized, which, nameCursor, names.length);
         if (MTYPE_ARG >= INARG_LIMIT) {
             assert(names[MTYPE_ARG] == null);
-            names[MTYPE_ARG] = BoundMethodHandle.getSpeciesData("L").getterName(names[THIS_MH], 0);
+            NamedFunction getter = BoundMethodHandle.getSpeciesData("L").getterFunction(0);
+            names[MTYPE_ARG] = new Name(getter, names[THIS_MH]);
             // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
         }
 
         // Make the final call.  If isGeneric, then prepend the result of type checking.
-        MethodType outCallType;
-        Object[] outArgs;
+        MethodType outCallType = mtype.basicType();
+        Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
         Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
         if (!isGeneric) {
             names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
             // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
-            outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
-            outCallType = mtype;
-        } else if (customized) {
-            names[CHECK_TYPE] = new Name(NF_asType, names[CALL_MH], mtypeArg);
-            // mh.invokeGeneric(a*):R =>
-            //  let mt=TYPEOF(a*:R), tmh=asType(mh, mt);
-            //    tmh.invokeBasic(a*)
-            outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
-            outCallType = mtype;
         } else {
             names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
-            // mh.invokeGeneric(a*):R =>
-            //  let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt);
-            //    gamh.invokeBasic(mt, mh, a*)
-            final int PREPEND_GAMH = 0, PREPEND_MT = 1, PREPEND_COUNT = 2;
-            assert(GENERIC_INVOKER_SLOP == PREPEND_COUNT);
-            outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
-            // prepend arguments:
-            System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
-            outArgs[PREPEND_GAMH] = names[CHECK_TYPE];
-            outArgs[PREPEND_MT] = mtypeArg;
-            outCallType = mtype.insertParameterTypes(0, MethodType.class, MethodHandle.class);
+            // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*)
+            outArgs[0] = names[CHECK_TYPE];
         }
-        names[LINKER_CALL] = new Name(invokeBasicMethod(outCallType), outArgs);
+        names[LINKER_CALL] = new Name(outCallType, outArgs);
         lform = new LambdaForm(debugName, INARG_LIMIT, names);
         if (isLinker)
             lform.compileToBytecode();  // JVM needs a real methodOop
@@ -343,7 +333,6 @@
             lform = mtype.form().setCachedLambdaForm(which, lform);
         return lform;
     }
-    private static final int GENERIC_INVOKER_SLOP = 2;  // used elsewhere to avoid arity problems
 
     /*non-public*/ static
     WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
@@ -362,47 +351,53 @@
             throw newWrongMethodTypeException(expected, actual);
     }
 
-    /** Static definition of MethodHandle.invokeGeneric checking code. */
+    /** Static definition of MethodHandle.invokeGeneric checking code.
+     * Directly returns the type-adjusted MH to invoke, as follows:
+     * {@code (R)MH.invoke(a*) => MH.asType(TYPEOF(a*:R)).invokeBasic(a*)}
+     */
     /*non-public*/ static
     @ForceInline
     Object checkGenericType(Object mhObj, Object expectedObj) {
         MethodHandle mh = (MethodHandle) mhObj;
         MethodType expected = (MethodType) expectedObj;
-        //MethodType actual = mh.type();
-        MethodHandle gamh = expected.form().genericInvoker;
-        if (gamh != null)  return gamh;
-        return prepareForGenericCall(expected);
-    }
-
-    /**
-     * Returns an adapter GA for invoking a MH with type adjustments.
-     * The MethodType of the generic invocation site is prepended to MH
-     * and its arguments as follows:
-     * {@code (R)MH.invoke(A*) => GA.invokeBasic(TYPEOF<A*,R>, MH, A*)}
-     */
-    /*non-public*/ static MethodHandle prepareForGenericCall(MethodType mtype) {
-        // force any needed adapters to be preconstructed
-        MethodTypeForm form = mtype.form();
-        MethodHandle gamh = form.genericInvoker;
-        if (gamh != null)  return gamh;
-        try {
-            // Trigger adapter creation.
-            gamh = InvokeGeneric.generalInvokerOf(form.erasedType);
-            form.genericInvoker = gamh;
-            return gamh;
-        } catch (Exception ex) {
-            throw newInternalError("Exception while resolving inexact invoke", ex);
-        }
+        if (mh.type() == expected)  return mh;
+        MethodHandle atc = mh.asTypeCache;
+        if (atc != null && atc.type() == expected)  return atc;
+        return mh.asType(expected);
+        /* Maybe add more paths here.  Possible optimizations:
+         * for (R)MH.invoke(a*),
+         * let MT0 = TYPEOF(a*:R), MT1 = MH.type
+         *
+         * if MT0==MT1 or MT1 can be safely called by MT0
+         *  => MH.invokeBasic(a*)
+         * if MT1 can be safely called by MT0[R := Object]
+         *  => MH.invokeBasic(a*) & checkcast(R)
+         * if MT1 can be safely called by MT0[* := Object]
+         *  => checkcast(A)* & MH.invokeBasic(a*) & checkcast(R)
+         * if a big adapter BA can be pulled out of (MT0,MT1)
+         *  => BA.invokeBasic(MT0,MH,a*)
+         * if a local adapter LA can cached on static CS0 = new GICS(MT0)
+         *  => CS0.LA.invokeBasic(MH,a*)
+         * else
+         *  => MH.asType(MT0).invokeBasic(A*)
+         */
     }
 
     static MemberName linkToCallSiteMethod(MethodType mtype) {
-        LambdaForm lform = callSiteForm(mtype);
+        LambdaForm lform = callSiteForm(mtype, false);
         return lform.vmentry;
     }
 
-    private static LambdaForm callSiteForm(MethodType mtype) {
+    static MemberName linkToTargetMethod(MethodType mtype) {
+        LambdaForm lform = callSiteForm(mtype, true);
+        return lform.vmentry;
+    }
+
+    // skipCallSite is true if we are optimizing a ConstantCallSite
+    private static LambdaForm callSiteForm(MethodType mtype, boolean skipCallSite) {
         mtype = mtype.basicType();  // normalize Z to I, String to Object, etc.
-        LambdaForm lform = mtype.form().cachedLambdaForm(MethodTypeForm.LF_CS_LINKER);
+        final int which = (skipCallSite ? MethodTypeForm.LF_MH_LINKER : MethodTypeForm.LF_CS_LINKER);
+        LambdaForm lform = mtype.form().cachedLambdaForm(which);
         if (lform != null)  return lform;
         // exactInvokerForm (Object,Object)Object
         //   link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
@@ -410,24 +405,26 @@
         final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
         final int INARG_LIMIT  = OUTARG_LIMIT + 1;
         int nameCursor = OUTARG_LIMIT;
-        final int CSITE_ARG    = nameCursor++;  // the last in-argument
-        final int CALL_MH      = nameCursor++;  // result of getTarget
+        final int APPENDIX_ARG = nameCursor++;  // the last in-argument
+        final int CSITE_ARG    = skipCallSite ? -1 : APPENDIX_ARG;
+        final int CALL_MH      = skipCallSite ? APPENDIX_ARG : nameCursor++;  // result of getTarget
         final int LINKER_CALL  = nameCursor++;
-        MethodType invokerFormType = mtype.appendParameterTypes(CallSite.class);
+        MethodType invokerFormType = mtype.appendParameterTypes(skipCallSite ? MethodHandle.class : CallSite.class);
         Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
         assert(names.length == nameCursor);
-        assert(names[CSITE_ARG] != null);
-        names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]);
+        assert(names[APPENDIX_ARG] != null);
+        if (!skipCallSite)
+            names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]);
         // (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
         final int PREPEND_MH = 0, PREPEND_COUNT = 1;
         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
         // prepend MH argument:
         System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
         outArgs[PREPEND_MH] = names[CALL_MH];
-        names[LINKER_CALL] = new Name(invokeBasicMethod(mtype), outArgs);
-        lform = new LambdaForm("linkToCallSite", INARG_LIMIT, names);
+        names[LINKER_CALL] = new Name(mtype, outArgs);
+        lform = new LambdaForm((skipCallSite ? "linkToTargetMethod" : "linkToCallSite"), INARG_LIMIT, names);
         lform.compileToBytecode();  // JVM needs a real methodOop
-        lform = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_CS_LINKER, lform);
+        lform = mtype.form().setCachedLambdaForm(which, lform);
         return lform;
     }
 
--- a/src/share/classes/java/lang/invoke/LambdaForm.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/LambdaForm.java	Tue Oct 08 14:57:32 2013 -0700
@@ -50,7 +50,7 @@
  * The result of the lambda is defined as one of the names, often the last one.
  * <p>
  * Here is an approximate grammar:
- * <pre>
+ * <blockquote><pre>{@code
  * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
  * ArgName = "a" N ":" T
  * TempName = "t" N ":" T "=" Function "(" Argument* ");"
@@ -60,7 +60,7 @@
  * NameRef = "a" N | "t" N
  * N = (any whole number)
  * T = "L" | "I" | "J" | "F" | "D" | "V"
- * </pre>
+ * }</pre></blockquote>
  * Names are numbered consecutively from left to right starting at zero.
  * (The letters are merely a taste of syntax sugar.)
  * Thus, the first temporary (if any) is always numbered N (where N=arity).
@@ -69,7 +69,7 @@
  * A lambda has a void result if and only if its result index is -1.
  * If a temporary has the type "V", it cannot be the subject of a NameRef,
  * even though possesses a number.
- * Note that all reference types are erased to "L", which stands for {@code Object).
+ * Note that all reference types are erased to "L", which stands for {@code Object}.
  * All subword types (boolean, byte, short, char) are erased to "I" which is {@code int}.
  * The other types stand for the usual primitive types.
  * <p>
@@ -89,7 +89,7 @@
  * encoded by using temporary expressions which call type-transformed identity functions.
  * <p>
  * Examples:
- * <pre>
+ * <blockquote><pre>{@code
  * (a0:J)=>{ a0 }
  *     == identity(long)
  * (a0:I)=>{ t1:V = System.out#println(a0); void }
@@ -113,14 +113,14 @@
  * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
  *                 t3:L = Class#cast(t2,a1); t3 }
  *     == invoker for identity method handle which performs cast
- * </pre>
+ * }</pre></blockquote>
  * <p>
  * @author John Rose, JSR 292 EG
  */
 class LambdaForm {
     final int arity;
     final int result;
-    final Name[] names;
+    @Stable final Name[] names;
     final String debugName;
     MemberName vmentry;   // low-level behavior, or null if not yet prepared
     private boolean isCompiled;
@@ -457,7 +457,7 @@
             isCompiled = true;
             return vmentry;
         } catch (Error | Exception ex) {
-            throw newInternalError(this.toString(), ex);
+            throw newInternalError("compileToBytecode", ex);
         }
     }
 
@@ -683,8 +683,9 @@
     */
 
     static void traceInterpreter(String event, Object obj, Object... args) {
-        if (!TRACE_INTERPRETER)  return;
-        System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : ""));
+        if (TRACE_INTERPRETER) {
+            System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : ""));
+        }
     }
     static void traceInterpreter(String event, Object obj) {
         traceInterpreter(event, obj, (Object[])null);
@@ -971,8 +972,8 @@
 
     static class NamedFunction {
         final MemberName member;
-        MethodHandle resolvedHandle;
-        MethodHandle invoker;
+        @Stable MethodHandle resolvedHandle;
+        @Stable MethodHandle invoker;
 
         NamedFunction(MethodHandle resolvedHandle) {
             this(resolvedHandle.internalMemberName(), resolvedHandle);
@@ -982,6 +983,16 @@
             //resolvedHandle = eraseSubwordTypes(resolvedHandle);
             this.resolvedHandle = resolvedHandle;
         }
+        NamedFunction(MethodType basicInvokerType) {
+            assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType;
+            if (basicInvokerType.parameterSlotCount() < MethodType.MAX_MH_INVOKER_ARITY) {
+                this.resolvedHandle = basicInvokerType.invokers().basicInvoker();
+                this.member = resolvedHandle.internalMemberName();
+            } else {
+                // necessary to pass BigArityTest
+                this.member = Invokers.invokeBasicMethod(basicInvokerType);
+            }
+        }
 
         // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
         // Any LambdaForm containing such a member is not interpretable.
@@ -1229,7 +1240,7 @@
         }
 
         public String toString() {
-            if (member == null)  return resolvedHandle.toString();
+            if (member == null)  return String.valueOf(resolvedHandle);
             return member.getDeclaringClass().getSimpleName()+"."+member.getName();
         }
     }
@@ -1267,7 +1278,7 @@
         final char type;
         private short index;
         final NamedFunction function;
-        final Object[] arguments;
+        @Stable final Object[] arguments;
 
         private Name(int index, char type, NamedFunction function, Object[] arguments) {
             this.index = (short)index;
@@ -1279,6 +1290,10 @@
         Name(MethodHandle function, Object... arguments) {
             this(new NamedFunction(function), arguments);
         }
+        Name(MethodType functionType, Object... arguments) {
+            this(new NamedFunction(functionType), arguments);
+            assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == 'L');
+        }
         Name(MemberName function, Object... arguments) {
             this(new NamedFunction(function), arguments);
         }
@@ -1426,8 +1441,6 @@
          * Does this Name precede the given binding node in some canonical order?
          * This predicate is used to order data bindings (via insertion sort)
          * with some stability.
-         * @param binding
-         * @return
          */
         boolean isSiblingBindingBefore(Name binding) {
             assert(!binding.isParam());
@@ -1622,4 +1635,12 @@
  */
 
     static { NamedFunction.initializeInvokers(); }
+
+    // The following hack is necessary in order to suppress TRACE_INTERPRETER
+    // during execution of the static initializes of this class.
+    // Turning on TRACE_INTERPRETER too early will cause
+    // stack overflows and other misbehavior during attempts to trace events
+    // that occur during LambdaForm.<clinit>.
+    // Therefore, do not move this line higher in this file, and do not remove.
+    private static final boolean TRACE_INTERPRETER = MethodHandleStatics.TRACE_INTERPRETER;
 }
--- a/src/share/classes/java/lang/invoke/MemberName.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MemberName.java	Tue Oct 08 14:57:32 2013 -0700
@@ -70,13 +70,13 @@
  * @author jrose
  */
 /*non-public*/ final class MemberName implements Member, Cloneable {
-    private Class<?>   clazz;       // class in which the method is defined
-    private String     name;        // may be null if not yet materialized
-    private Object     type;        // may be null if not yet materialized
-    private int        flags;       // modifier bits; see reflect.Modifier
+    private Class<?> clazz;       // class in which the method is defined
+    private String   name;        // may be null if not yet materialized
+    private Object   type;        // may be null if not yet materialized
+    private int      flags;       // modifier bits; see reflect.Modifier
     //@Injected JVM_Method* vmtarget;
     //@Injected int         vmindex;
-    private Object     resolution;  // if null, this guy is resolved
+    private Object   resolution;  // if null, this guy is resolved
 
     /** Return the declaring class of this member.
      *  In the case of a bare name and type, the declaring class will be null.
@@ -98,7 +98,9 @@
     public String getName() {
         if (name == null) {
             expandFromVM();
-            if (name == null)  return null;
+            if (name == null) {
+                return null;
+            }
         }
         return name;
     }
@@ -119,28 +121,39 @@
     public MethodType getMethodType() {
         if (type == null) {
             expandFromVM();
-            if (type == null)  return null;
+            if (type == null) {
+                return null;
+            }
+        }
+        if (!isInvocable()) {
+            throw newIllegalArgumentException("not invocable, no method type");
         }
-        if (!isInvocable())
-            throw newIllegalArgumentException("not invocable, no method type");
-        if (type instanceof MethodType) {
-            return (MethodType) type;
+
+        {
+            // Get a snapshot of type which doesn't get changed by racing threads.
+            final Object type = this.type;
+            if (type instanceof MethodType) {
+                return (MethodType) type;
+            }
         }
-        if (type instanceof String) {
-            String sig = (String) type;
-            MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
-            this.type = res;
-            return res;
+
+        // type is not a MethodType yet.  Convert it thread-safely.
+        synchronized (this) {
+            if (type instanceof String) {
+                String sig = (String) type;
+                MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader());
+                type = res;
+            } else if (type instanceof Object[]) {
+                Object[] typeInfo = (Object[]) type;
+                Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
+                Class<?> rtype = (Class<?>) typeInfo[0];
+                MethodType res = MethodType.methodType(rtype, ptypes);
+                type = res;
+            }
+            // Make sure type is a MethodType for racing threads.
+            assert type instanceof MethodType : "bad method type " + type;
         }
-        if (type instanceof Object[]) {
-            Object[] typeInfo = (Object[]) type;
-            Class<?>[] ptypes = (Class<?>[]) typeInfo[1];
-            Class<?> rtype = (Class<?>) typeInfo[0];
-            MethodType res = MethodType.methodType(rtype, ptypes);
-            this.type = res;
-            return res;
-        }
-        throw new InternalError("bad method type "+type);
+        return (MethodType) type;
     }
 
     /** Return the actual type under which this method or constructor must be invoked.
@@ -173,21 +186,34 @@
     public Class<?> getFieldType() {
         if (type == null) {
             expandFromVM();
-            if (type == null)  return null;
+            if (type == null) {
+                return null;
+            }
         }
-        if (isInvocable())
+        if (isInvocable()) {
             throw newIllegalArgumentException("not a field or nested class, no simple type");
-        if (type instanceof Class<?>) {
-            return (Class<?>) type;
         }
-        if (type instanceof String) {
-            String sig = (String) type;
-            MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
-            Class<?> res = mtype.returnType();
-            this.type = res;
-            return res;
+
+        {
+            // Get a snapshot of type which doesn't get changed by racing threads.
+            final Object type = this.type;
+            if (type instanceof Class<?>) {
+                return (Class<?>) type;
+            }
         }
-        throw new InternalError("bad field type "+type);
+
+        // type is not a Class yet.  Convert it thread-safely.
+        synchronized (this) {
+            if (type instanceof String) {
+                String sig = (String) type;
+                MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader());
+                Class<?> res = mtype.returnType();
+                type = res;
+            }
+            // Make sure type is a Class for racing threads.
+            assert type instanceof Class<?> : "bad field type " + type;
+        }
+        return (Class<?>) type;
     }
 
     /** Utility method to produce either the method type or field type of this member. */
@@ -201,10 +227,10 @@
     public String getSignature() {
         if (type == null) {
             expandFromVM();
-            if (type == null)  return null;
+            if (type == null) {
+                return null;
+            }
         }
-        if (type instanceof String)
-            return (String) type;
         if (isInvocable())
             return BytecodeDescriptor.unparse(getMethodType());
         else
@@ -463,10 +489,17 @@
         //assert(referenceKindIsConsistent());  // do this after resolution
     }
 
+    /**
+     * Calls down to the VM to fill in the fields.  This method is
+     * synchronized to avoid racing calls.
+     */
     private void expandFromVM() {
-        if (!isResolved())  return;
-        if (type instanceof Object[])
-            type = null;  // don't saddle JVM w/ typeInfo
+        if (type != null) {
+            return;
+        }
+        if (!isResolved()) {
+            return;
+        }
         MethodHandleNatives.expand(this);
     }
 
@@ -523,6 +556,9 @@
         }
         throw new IllegalArgumentException(this.toString());
     }
+    /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind.
+     *  In that case it must already be REF_invokeSpecial.
+     */
     public MemberName asConstructor() {
         switch (getReferenceKind()) {
         case REF_invokeSpecial:     return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
@@ -530,6 +566,32 @@
         }
         throw new IllegalArgumentException(this.toString());
     }
+    /** If this MN is a REF_invokeSpecial, return a clone with the "normal" kind
+     *  REF_invokeVirtual; also switch either to REF_invokeInterface if clazz.isInterface.
+     *  The end result is to get a fully virtualized version of the MN.
+     *  (Note that resolving in the JVM will sometimes devirtualize, changing
+     *  REF_invokeVirtual of a final to REF_invokeSpecial, and REF_invokeInterface
+     *  in some corner cases to either of the previous two; this transform
+     *  undoes that change under the assumption that it occurred.)
+     */
+    public MemberName asNormalOriginal() {
+        byte normalVirtual = clazz.isInterface() ? REF_invokeInterface : REF_invokeVirtual;
+        byte refKind = getReferenceKind();
+        byte newRefKind = refKind;
+        MemberName result = this;
+        switch (refKind) {
+        case REF_invokeInterface:
+        case REF_invokeVirtual:
+        case REF_invokeSpecial:
+            newRefKind = normalVirtual;
+            break;
+        }
+        if (newRefKind == refKind)
+            return this;
+        result = clone().changeReferenceKind(newRefKind, refKind);
+        assert(this.referenceKindIsConsistentWith(result.getReferenceKind()));
+        return result;
+    }
     /** Create a name for the given reflected constructor.  The resulting name will be in a resolved state. */
     @SuppressWarnings("LeakingThisInConstructor")
     public MemberName(Constructor<?> ctor) {
@@ -627,7 +689,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(clazz, flags, name, getType());
+        return Objects.hash(clazz, getReferenceKind(), name, getType());
     }
     @Override
     public boolean equals(Object that) {
@@ -643,13 +705,14 @@
         if (this == that)  return true;
         if (that == null)  return false;
         return this.clazz == that.clazz
-                && this.flags == that.flags
+                && this.getReferenceKind() == that.getReferenceKind()
                 && Objects.equals(this.name, that.name)
                 && Objects.equals(this.getType(), that.getType());
     }
 
     // Construction from symbolic parts, for queries:
-    /** Create a field or type name from the given components:  Declaring class, name, type, reference kind.
+    /** Create a field or type name from the given components:
+     *  Declaring class, name, type, reference kind.
      *  The declaring class may be supplied as null if this is to be a bare name and type.
      *  The resulting name will in an unresolved state.
      */
@@ -673,21 +736,34 @@
      *  The resulting name will in an unresolved state.
      */
     public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
-        @SuppressWarnings("LocalVariableHidesMemberVariable")
-        int flags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
-        init(defClass, name, type, flagsMods(flags, 0, refKind));
+        int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
+        init(defClass, name, type, flagsMods(initFlags, 0, refKind));
         initResolved(false);
     }
-//    /** Create a method or constructor name from the given components:  Declaring class, name, type, modifiers.
-//     *  It will be a constructor if and only if the name is {@code "&lt;init&gt;"}.
-//     *  The declaring class may be supplied as null if this is to be a bare name and type.
-//     *  The modifier flags default to zero.
-//     *  The resulting name will in an unresolved state.
-//     */
-//    public MemberName(Class<?> defClass, String name, MethodType type, Void unused) {
-//        this(defClass, name, type, REF_NONE);
-//    }
-
+    /** Create a method, constructor, or field name from the given components:
+     *  Reference kind, declaring class, name, type.
+     */
+    public MemberName(byte refKind, Class<?> defClass, String name, Object type) {
+        int kindFlags;
+        if (MethodHandleNatives.refKindIsField(refKind)) {
+            kindFlags = IS_FIELD;
+            if (!(type instanceof Class))
+                throw newIllegalArgumentException("not a field type");
+        } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
+            kindFlags = IS_METHOD;
+            if (!(type instanceof MethodType))
+                throw newIllegalArgumentException("not a method type");
+        } else if (refKind == REF_newInvokeSpecial) {
+            kindFlags = IS_CONSTRUCTOR;
+            if (!(type instanceof MethodType) ||
+                !CONSTRUCTOR_NAME.equals(name))
+                throw newIllegalArgumentException("not a constructor type or name");
+        } else {
+            throw newIllegalArgumentException("bad reference kind "+refKind);
+        }
+        init(defClass, name, type, flagsMods(kindFlags, 0, refKind));
+        initResolved(false);
+    }
     /** Query whether this member name is resolved to a non-static, non-final method.
      */
     public boolean hasReceiverTypeDispatch() {
--- a/src/share/classes/java/lang/invoke/MethodHandle.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandle.java	Tue Oct 08 14:57:32 2013 -0700
@@ -292,7 +292,7 @@
  * generates a single invokevirtual instruction with
  * the symbolic type descriptor indicated in the following comment.
  * In these examples, the helper method {@code assertEquals} is assumed to
- * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals }
+ * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals}
  * on its arguments, and asserts that the result is true.
  *
  * <h1>Exceptions</h1>
@@ -392,7 +392,7 @@
  * Java types.
  * <ul>
  * <li>Method types range over all possible arities,
- * from no arguments to up to 255 of arguments (a limit imposed by the JVM).
+ * from no arguments to up to the  <a href="MethodHandle.html#maxarity">maximum number</a> of allowed arguments.
  * Generics are not variadic, and so cannot represent this.</li>
  * <li>Method types can specify arguments of primitive types,
  * which Java generic types cannot range over.</li>
@@ -402,6 +402,22 @@
  * genericity with a Java type parameter.</li>
  * </ul>
  *
+ * <h1><a name="maxarity"></a>Arity limits</h1>
+ * The JVM imposes on all methods and constructors of any kind an absolute
+ * limit of 255 stacked arguments.  This limit can appear more restrictive
+ * in certain cases:
+ * <ul>
+ * <li>A {@code long} or {@code double} argument counts (for purposes of arity limits) as two argument slots.
+ * <li>A non-static method consumes an extra argument for the object on which the method is called.
+ * <li>A constructor consumes an extra argument for the object which is being constructed.
+ * <li>Since a method handle&rsquo;s {@code invoke} method (or other signature-polymorphic method) is non-virtual,
+ *     it consumes an extra argument for the method handle itself, in addition to any non-virtual receiver object.
+ * </ul>
+ * These limits imply that certain method handles cannot be created, solely because of the JVM limit on stacked arguments.
+ * For example, if a static JVM method accepts exactly 255 arguments, a method handle cannot be created for it.
+ * Attempts to create method handles with impossible method types lead to an {@link IllegalArgumentException}.
+ * In particular, a method handle&rsquo;s type must not have an arity of the exact maximum 255.
+ *
  * @see MethodType
  * @see MethodHandles
  * @author John Rose, JSR 292 EG
@@ -420,6 +436,8 @@
     private final MethodType type;
     /*private*/ final LambdaForm form;
     // form is not private so that invokers can easily fetch it
+    /*private*/ MethodHandle asTypeCache;
+    // asTypeCache is not private so that invokers can easily fetch it
 
     /**
      * Reports the type of this method handle.
@@ -557,10 +575,10 @@
     /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
 
     /**
-     * Performs a variable arity invocation, passing the arguments in the given array
+     * Performs a variable arity invocation, passing the arguments in the given list
      * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
      * which mentions only the type {@code Object}, and whose arity is the length
-     * of the argument array.
+     * of the argument list.
      * <p>
      * Specifically, execution proceeds as if by the following steps,
      * although the methods are not guaranteed to be called if the JVM
@@ -590,10 +608,10 @@
      * or forced to null if the return type is void.
      * <p>
      * This call is equivalent to the following code:
-     * <p><blockquote><pre>
+     * <p><blockquote><pre>{@code
      * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0);
      * Object result = invoker.invokeExact(this, arguments);
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p>
      * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke},
      * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
@@ -626,7 +644,7 @@
      * <p>
      * This method is also equivalent to the following code:
      * <p><blockquote><pre>
-     * {@link #invokeWithArguments(Object...) invokeWithArguments}(arguments.toArray())
+     * {@link #invokeWithArguments(Object...) invokeWithArguments}{@code(arguments.toArray())}
      * </pre></blockquote>
      *
      * @param arguments the arguments to pass to the target
@@ -739,10 +757,24 @@
      * @see MethodHandles#explicitCastArguments
      */
     public MethodHandle asType(MethodType newType) {
-        if (!type.isConvertibleTo(newType)) {
+        // Fast path alternative to a heavyweight {@code asType} call.
+        // Return 'this' if the conversion will be a no-op.
+        if (newType == type) {
+            return this;
+        }
+        // Return 'this.asTypeCache' if the conversion is already memoized.
+        MethodHandle atc = asTypeCache;
+        if (atc != null && newType == atc.type) {
+            return atc;
+        }
+        return asTypeUncached(newType);
+    }
+
+    /** Override this to change asType behavior. */
+    /*non-public*/ MethodHandle asTypeUncached(MethodType newType) {
+        if (!type.isConvertibleTo(newType))
             throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
-        }
-        return convertArguments(newType);
+        return asTypeCache = convertArguments(newType);
     }
 
     /**
@@ -772,6 +804,10 @@
      * to the target method handle.
      * (The array may also be null when zero elements are required.)
      * <p>
+     * If, when the adapter is called, the supplied array argument does
+     * not have the correct number of elements, the adapter will throw
+     * an {@link IllegalArgumentException} instead of invoking the target.
+     * <p>
      * Here are some simple examples of array-spreading method handles:
      * <blockquote><pre>{@code
 MethodHandle equals = publicLookup()
@@ -782,6 +818,12 @@
 MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
 assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
 assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
+// try to spread from anything but a 2-array:
+for (int n = 0; n <= 10; n++) {
+  Object[] badArityArgs = (n == 2 ? null : new Object[n]);
+  try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
+  catch (IllegalArgumentException ex) { } // OK
+}
 // spread both arguments from a String array:
 MethodHandle eq2s = equals.asSpreader(String[].class, 2);
 assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
@@ -815,10 +857,12 @@
      * @return a new method handle which spreads its final array argument,
      *         before calling the original method handle
      * @throws NullPointerException if {@code arrayType} is a null reference
-     * @throws IllegalArgumentException if {@code arrayType} is not an array type
-     * @throws IllegalArgumentException if target does not have at least
+     * @throws IllegalArgumentException if {@code arrayType} is not an array type,
+     *         or if target does not have at least
      *         {@code arrayLength} parameter types,
-     *         or if {@code arrayLength} is negative
+     *         or if {@code arrayLength} is negative,
+     *         or if the resulting method handle's type would have
+     *         <a href="MethodHandle.html#maxarity">too many parameters</a>
      * @throws WrongMethodTypeException if the implied {@code asType} call fails
      * @see #asCollector
      */
@@ -931,7 +975,9 @@
      * @throws NullPointerException if {@code arrayType} is a null reference
      * @throws IllegalArgumentException if {@code arrayType} is not an array type
      *         or {@code arrayType} is not assignable to this method handle's trailing parameter type,
-     *         or {@code arrayLength} is not a legal array size
+     *         or {@code arrayLength} is not a legal array size,
+     *         or the resulting method handle's type would have
+     *         <a href="MethodHandle.html#maxarity">too many parameters</a>
      * @throws WrongMethodTypeException if the implied {@code asType} call fails
      * @see #asSpreader
      * @see #asVarargsCollector
@@ -1226,9 +1272,9 @@
      * starting with the string {@code "MethodHandle"} and
      * ending with the string representation of the method handle's type.
      * In other words, this method returns a string equal to the value of:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * "MethodHandle" + type().toString()
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p>
      * (<em>Note:</em>  Future releases of this API may add further information
      * to the string representation.
@@ -1285,6 +1331,11 @@
     }
 
     /*non-public*/
+    Class<?> internalCallerClass() {
+        return null;  // caller-bound MH for @CallerSensitive method returns caller
+    }
+
+    /*non-public*/
     MethodHandle withInternalMemberName(MemberName member) {
         if (member != null) {
             return MethodHandleImpl.makeWrappedMember(this, member);
@@ -1434,7 +1485,6 @@
      * Threads may continue running the old form indefinitely,
      * but it is likely that the new one will be preferred for new executions.
      * Use with discretion.
-     * @param newForm
      */
     /*non-public*/
     void updateForm(LambdaForm newForm) {
--- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Oct 08 14:57:32 2013 -0700
@@ -314,13 +314,13 @@
     static class AsVarargsCollector extends MethodHandle {
         private final MethodHandle target;
         private final Class<?> arrayType;
-        private MethodHandle cache;
+        private /*@Stable*/ MethodHandle asCollectorCache;
 
         AsVarargsCollector(MethodHandle target, MethodType type, Class<?> arrayType) {
             super(type, reinvokerForm(target));
             this.target = target;
             this.arrayType = arrayType;
-            this.cache = target.asCollector(arrayType, 0);
+            this.asCollectorCache = target.asCollector(arrayType, 0);
         }
 
         @Override MethodHandle reinvokerTarget() { return target; }
@@ -336,18 +336,19 @@
         }
 
         @Override
-        public MethodHandle asType(MethodType newType) {
+        public MethodHandle asTypeUncached(MethodType newType) {
             MethodType type = this.type();
             int collectArg = type.parameterCount() - 1;
             int newArity = newType.parameterCount();
             if (newArity == collectArg+1 &&
                 type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
                 // if arity and trailing parameter are compatible, do normal thing
-                return asFixedArity().asType(newType);
+                return asTypeCache = asFixedArity().asType(newType);
             }
             // check cache
-            if (cache.type().parameterCount() == newArity)
-                return cache.asType(newType);
+            MethodHandle acc = asCollectorCache;
+            if (acc != null && acc.type().parameterCount() == newArity)
+                return asTypeCache = acc.asType(newType);
             // build and cache a collector
             int arrayLength = newArity - collectArg;
             MethodHandle collector;
@@ -357,8 +358,8 @@
             } catch (IllegalArgumentException ex) {
                 throw new WrongMethodTypeException("cannot build collector", ex);
             }
-            cache = collector;
-            return collector.asType(newType);
+            asCollectorCache = collector;
+            return asTypeCache = collector.asType(newType);
         }
 
         @Override
@@ -380,6 +381,10 @@
         MemberName internalMemberName() {
             return asFixedArity().internalMemberName();
         }
+        @Override
+        Class<?> internalCallerClass() {
+            return asFixedArity().internalCallerClass();
+        }
 
         /*non-public*/
         @Override
@@ -435,7 +440,7 @@
                 // Spread the array.
                 MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
                 Name array = names[argIndex];
-                names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount);
+                names[nameCursor++] = new Name(Lazy.NF_checkSpreadArgument, array, spreadArgCount);
                 for (int j = 0; j < spreadArgCount; i++, j++) {
                     indexes[i] = nameCursor;
                     names[nameCursor++] = new Name(aload, array, j);
@@ -459,14 +464,8 @@
     }
 
     static void checkSpreadArgument(Object av, int n) {
-        // FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE
-        // but the actual exception raised by an arity mismatch should be WMTE
-        final boolean RAISE_RANDOM_EXCEPTIONS = true;  // FIXME: delete in JSR 292 M1
         if (av == null) {
             if (n == 0)  return;
-            int len;
-            if (RAISE_RANDOM_EXCEPTIONS)
-                len = ((Object[])av).length;  // throw NPE; but delete this after tests are fixed
         } else if (av instanceof Object[]) {
             int len = ((Object[])av).length;
             if (len == n)  return;
@@ -475,19 +474,23 @@
             if (len == n)  return;
         }
         // fall through to error:
-        if (RAISE_RANDOM_EXCEPTIONS)
-            throw newIllegalArgumentException("Array is not of length "+n);
-        throw new WrongMethodTypeException("Array is not of length "+n);
+        throw newIllegalArgumentException("array is not of length "+n);
     }
 
-    private static final NamedFunction NF_checkSpreadArgument;
-    static {
-        try {
-            NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
-                    .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
-            NF_checkSpreadArgument.resolve();
-        } catch (ReflectiveOperationException ex) {
-            throw newInternalError(ex);
+    /**
+     * Pre-initialized NamedFunctions for bootstrapping purposes.
+     * Factored in an inner class to delay initialization until first usage.
+     */
+    private static class Lazy {
+        static final NamedFunction NF_checkSpreadArgument;
+        static {
+            try {
+                NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
+                        .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
+                NF_checkSpreadArgument.resolve();
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError(ex);
+            }
         }
     }
 
@@ -832,7 +835,7 @@
             MethodHandle vamh = prepareForInvoker(mh);
             // Cache the result of makeInjectedInvoker once per argument class.
             MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
-            return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName());
+            return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName(), hostClass);
         }
 
         private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
@@ -887,10 +890,12 @@
         }
 
         // Undo the adapter effect of prepareForInvoker:
-        private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) {
+        private static MethodHandle restoreToType(MethodHandle vamh, MethodType type,
+                                                  MemberName member,
+                                                  Class<?> hostClass) {
             MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount());
             mh = mh.asType(type);
-            mh = mh.withInternalMemberName(member);
+            mh = new WrappedMember(mh, type, member, hostClass);
             return mh;
         }
 
@@ -959,11 +964,13 @@
     static class WrappedMember extends MethodHandle {
         private final MethodHandle target;
         private final MemberName member;
+        private final Class<?> callerClass;
 
-        private WrappedMember(MethodHandle target, MethodType type, MemberName member) {
+        private WrappedMember(MethodHandle target, MethodType type, MemberName member, Class<?> callerClass) {
             super(type, reinvokerForm(target));
             this.target = target;
             this.member = member;
+            this.callerClass = callerClass;
         }
 
         @Override
@@ -971,23 +978,33 @@
             return target;
         }
         @Override
+        public MethodHandle asTypeUncached(MethodType newType) {
+            // This MH is an alias for target, except for the MemberName
+            // Drop the MemberName if there is any conversion.
+            return asTypeCache = target.asType(newType);
+        }
+        @Override
         MemberName internalMemberName() {
             return member;
         }
         @Override
+        Class<?> internalCallerClass() {
+            return callerClass;
+        }
+        @Override
         boolean isInvokeSpecial() {
             return target.isInvokeSpecial();
         }
         @Override
         MethodHandle viewAsType(MethodType newType) {
-            return new WrappedMember(target, newType, member);
+            return new WrappedMember(target, newType, member, callerClass);
         }
     }
 
     static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) {
         if (member.equals(target.internalMemberName()))
             return target;
-        return new WrappedMember(target, target.type(), member);
+        return new WrappedMember(target, target.type(), member, null);
     }
 
 }
--- a/src/share/classes/java/lang/invoke/MethodHandleInfo.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandleInfo.java	Tue Oct 08 14:57:32 2013 -0700
@@ -32,9 +32,10 @@
 import static java.lang.invoke.MethodHandleStatics.*;
 
 /**
- * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts.
+ * A symbolic reference obtained by cracking a direct method handle
+ * into its consitutent symbolic parts.
  * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}.
- * <p>
+ * <h1><a name="directmh"></a>Direct Method Handles</h1>
  * A <em>direct method handle</em> represents a method, constructor, or field without
  * any intervening argument bindings or other transformations.
  * The method, constructor, or field referred to by a direct method handle is called
@@ -56,11 +57,25 @@
  *     or {@link Lookup#unreflectSetter Lookup.unreflectSetter}
  *     to convert a {@link Field} into a method handle.
  * </ul>
- * In all of these cases, it is possible to crack the resulting direct method handle
+ *
+ * <h1>Restrictions on Cracking</h1>
+ * Given a suitable {@code Lookup} object, it is possible to crack any direct method handle
  * to recover a symbolic reference for the underlying method, constructor, or field.
  * Cracking must be done via a {@code Lookup} object equivalent to that which created
  * the target method handle, or which has enough access permissions to recreate
  * an equivalent method handle.
+ * <p>
+ * If the underlying method is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>,
+ * the direct method handle will have been "bound" to a particular caller class, the
+ * {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class}
+ * of the lookup object used to create it.
+ * Cracking this method handle with a different lookup class will fail
+ * even if the underlying method is public (like {@code Class.forName}).
+ * <p>
+ * The requirement of lookup object matching provides a "fast fail" behavior
+ * for programs which may otherwise trust erroneous revelation of a method
+ * handle with symbolic information (or caller binding) from an unexpected scope.
+ * Use {@link java.lang.invoke.MethodHandles#reflectAs} to override this limitation.
  *
  * <h1><a name="refkinds"></a>Reference kinds</h1>
  * The <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a>
@@ -190,7 +205,7 @@
      * @return the Java language modifiers for underlying member,
      *         or -1 if the member cannot be accessed
      * @see Modifier
-     * @see reflectAs
+     * @see #reflectAs
      */
     public int getModifiers();
 
--- a/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, 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
@@ -233,20 +233,19 @@
     }
     static String refKindName(byte refKind) {
         assert(refKindIsValid(refKind));
-        return REFERENCE_KIND_NAME[refKind];
+        switch (refKind) {
+        case REF_getField:          return "getField";
+        case REF_getStatic:         return "getStatic";
+        case REF_putField:          return "putField";
+        case REF_putStatic:         return "putStatic";
+        case REF_invokeVirtual:     return "invokeVirtual";
+        case REF_invokeStatic:      return "invokeStatic";
+        case REF_invokeSpecial:     return "invokeSpecial";
+        case REF_newInvokeSpecial:  return "newInvokeSpecial";
+        case REF_invokeInterface:   return "invokeInterface";
+        default:                    return "REF_???";
+        }
     }
-    private static String[] REFERENCE_KIND_NAME = {
-            null,
-            "getField",
-            "getStatic",
-            "putField",
-            "putStatic",
-            "invokeVirtual",
-            "invokeStatic",
-            "invokeSpecial",
-            "newInvokeSpecial",
-            "invokeInterface"
-    };
 
     private static native int getNamedCon(int which, Object[] name);
     static boolean verifyConstants() {
@@ -294,12 +293,18 @@
         Class<?> caller = (Class<?>)callerObj;
         String name = nameObj.toString().intern();
         MethodType type = (MethodType)typeObj;
-        appendixResult[0] = CallSite.makeSite(bootstrapMethod,
+        CallSite callSite = CallSite.makeSite(bootstrapMethod,
                                               name,
                                               type,
                                               staticArguments,
                                               caller);
-        return Invokers.linkToCallSiteMethod(type);
+        if (callSite instanceof ConstantCallSite) {
+            appendixResult[0] = callSite.dynamicInvoker();
+            return Invokers.linkToTargetMethod(type);
+        } else {
+            appendixResult[0] = callSite;
+            return Invokers.linkToCallSiteMethod(type);
+        }
     }
 
     /**
@@ -388,12 +393,7 @@
                                      Object[] appendixResult) {
         try {
             if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
-                switch (name) {
-                case "invoke":
-                    return Invokers.genericInvokerMethod(fixMethodType(callerClass, type), appendixResult);
-                case "invokeExact":
-                    return Invokers.exactInvokerMethod(fixMethodType(callerClass, type), appendixResult);
-                }
+                return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
             }
         } catch (Throwable ex) {
             if (ex instanceof LinkageError)
@@ -440,14 +440,34 @@
             Lookup lookup = IMPL_LOOKUP.in(callerClass);
             assert(refKindIsValid(refKind));
             return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
+        } catch (IllegalAccessException ex) {
+            Error err = new IllegalAccessError(ex.getMessage());
+            throw initCauseFrom(err, ex);
+        } catch (NoSuchMethodException ex) {
+            Error err = new NoSuchMethodError(ex.getMessage());
+            throw initCauseFrom(err, ex);
+        } catch (NoSuchFieldException ex) {
+            Error err = new NoSuchFieldError(ex.getMessage());
+            throw initCauseFrom(err, ex);
         } catch (ReflectiveOperationException ex) {
             Error err = new IncompatibleClassChangeError();
-            err.initCause(ex);
-            throw err;
+            throw initCauseFrom(err, ex);
         }
     }
 
     /**
+     * Use best possible cause for err.initCause(), substituting the
+     * cause for err itself if the cause has the same (or better) type.
+     */
+    static private Error initCauseFrom(Error err, Exception ex) {
+        Throwable th = ex.getCause();
+        if (err.getClass().isInstance(th))
+           return (Error) th;
+        err.initCause(th == null ? ex : th);
+        return err;
+    }
+
+    /**
      * Is this method a caller-sensitive method?
      * I.e., does it call Reflection.getCallerClass or a similer method
      * to ask about the identity of its caller?
--- a/src/share/classes/java/lang/invoke/MethodHandleProxies.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandleProxies.java	Tue Oct 08 14:57:32 2013 -0700
@@ -107,6 +107,11 @@
      * such as abstract classes with single abstract methods.
      * Future versions of this API may also equip wrapper instances
      * with one or more additional public "marker" interfaces.
+     * <p>
+     * If a security manager is installed, this method is caller sensitive.
+     * During any invocation of the target method handle via the returned wrapper,
+     * the original creator of the wrapper (the caller) will be visible
+     * to context checks requested by the security manager.
      *
      * @param <T> the desired type of the wrapper, a single-method interface
      * @param intfc a class object representing {@code T}
--- a/src/share/classes/java/lang/invoke/MethodHandles.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java	Tue Oct 08 14:57:32 2013 -0700
@@ -39,6 +39,7 @@
 import sun.security.util.SecurityConstants;
 import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import java.util.concurrent.ConcurrentHashMap;
 import sun.security.util.SecurityConstants;
 
 /**
@@ -48,7 +49,6 @@
  * <li>Lookup methods which help create method handles for methods and fields.
  * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
  * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
- * <li>Wrapper methods which can convert between method handles and interface types.
  * </ul>
  * <p>
  * @author John Rose, JSR 292 EG
@@ -65,12 +65,25 @@
     //// Method handle creation from ordinary methods.
 
     /**
-     * Returns a {@link Lookup lookup object} on the caller,
-     * which has the capability to access any method handle that the caller has access to,
-     * including direct method handles to private fields and methods.
+     * Returns a {@link Lookup lookup object} with
+     * full capabilities to emulate all supported bytecode behaviors of the caller.
+     * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller.
+     * Factory methods on the lookup object can create
+     * <a href="MethodHandleInfo.html#directmh">direct method handles</a>
+     * for any member that the caller has access to via bytecodes,
+     * including protected and private fields and methods.
      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
      * Do not store it in place where untrusted code can access it.
-     * @return a lookup object for the caller of this method
+     * <p>
+     * This method is caller sensitive, which means that it may return different
+     * values to different callers.
+     * <p>
+     * For any given caller class {@code C}, the lookup object returned by this call
+     * has equivalent capabilities to any lookup object
+     * supplied by the JVM to the bootstrap method of an
+     * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
+     * executing in the same caller class {@code C}.
+     * @return a lookup object for the caller of this method, with private access
      */
     @CallerSensitive
     public static Lookup lookup() {
@@ -84,11 +97,17 @@
      * <p>
      * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
      * of this lookup object will be {@link java.lang.Object}.
-     * <p>
+     *
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
      * The lookup class can be changed to any other class {@code C} using an expression of the form
-     * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
+     * {@link Lookup#in publicLookup().in(C.class)}.
      * Since all classes have equal access to public names,
      * such a change would confer no new access rights.
+     * A public lookup object is always subject to
+     * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
+     * Also, it cannot access
+     * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
      * @return a lookup object which is trusted minimally
      */
     public static Lookup publicLookup() {
@@ -96,7 +115,8 @@
     }
 
     /**
-     * Performs an unchecked "crack" of a direct method handle.
+     * Performs an unchecked "crack" of a
+     * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
      * The result is as if the user had obtained a lookup object capable enough
      * to crack the target method handle, called
      * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
@@ -149,10 +169,17 @@
      * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
      * The factory methods on a {@code Lookup} object correspond to all major
      * use cases for methods, constructors, and fields.
+     * Each method handle created by a factory method is the functional
+     * equivalent of a particular <em>bytecode behavior</em>.
+     * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
      * Here is a summary of the correspondence between these factory methods and
      * the behavior the resulting method handles:
      * <table border=1 cellpadding=5 summary="lookup method behaviors">
-     * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr>
+     * <tr>
+     *     <th><a name="equiv"></a>lookup expression</th>
+     *     <th>member</th>
+     *     <th>bytecode behavior</th>
+     * </tr>
      * <tr>
      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
      *     <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
@@ -228,10 +255,12 @@
      * In cases where the given member is of variable arity (i.e., a method or constructor)
      * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
      * In all other cases, the returned method handle will be of fixed arity.
-     * <p>
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
      * The equivalence between looked-up method handles and underlying
-     * class members can break down in a few ways:
-     * <ul>
+     * class members and bytecode behaviors
+     * can break down in a few ways:
+     * <ul style="font-size:smaller;">
      * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
      * the lookup can still succeed, even when there is no equivalent
      * Java expression or bytecoded constant.
@@ -241,9 +270,13 @@
      * For example, lookups for {@code MethodHandle.invokeExact} and
      * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
      * <li>If there is a security manager installed, it can forbid the lookup
-     * on various grounds (<a href="#secmgr">see below</a>).
-     * By contrast, the {@code ldc} instruction is not subject to
-     * security manager checks.
+     * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
+     * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
+     * constant is not subject to security manager checks.
+     * <li>If the looked-up method has a
+     * <a href="MethodHandle.html#maxarity">very large arity</a>,
+     * the method handle creation may fail, due to the method handle
+     * type having too many parameters.
      * </ul>
      *
      * <h1><a name="access"></a>Access checking</h1>
@@ -271,7 +304,8 @@
      * A lookup can fail, because
      * the containing class is not accessible to the lookup class, or
      * because the desired class member is missing, or because the
-     * desired class member is not accessible to the lookup class.
+     * desired class member is not accessible to the lookup class, or
+     * because the lookup object is not trusted enough to access the member.
      * In any of these cases, a {@code ReflectiveOperationException} will be
      * thrown from the attempted lookup.  The exact class will be one of
      * the following:
@@ -282,11 +316,23 @@
      * </ul>
      * <p>
      * In general, the conditions under which a method handle may be
-     * looked up for a method {@code M} are exactly equivalent to the conditions
-     * under which the lookup class could have compiled and resolved a call to {@code M}.
+     * looked up for a method {@code M} are no more restrictive than the conditions
+     * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
+     * Where the JVM would raise exceptions like {@code NoSuchMethodError},
+     * a method handle lookup will generally raise a corresponding
+     * checked exception, such as {@code NoSuchMethodException}.
      * And the effect of invoking the method handle resulting from the lookup
-     * is exactly equivalent to executing the compiled and resolved call to {@code M}.
+     * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
+     * to executing the compiled, verified, and resolved call to {@code M}.
      * The same point is true of fields and constructors.
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * Access checks only apply to named and reflected methods,
+     * constructors, and fields.
+     * Other method handle creation methods, such as
+     * {@link MethodHandle#asType MethodHandle.asType},
+     * do not require any access checks, and are used
+     * independently of any {@code Lookup} object.
      * <p>
      * If the desired member is {@code protected}, the usual JVM rules apply,
      * including the requirement that the lookup class must be either be in the
@@ -300,6 +346,18 @@
      * (which will necessarily be a superclass of the lookup class)
      * to the lookup class itself.
      * <p>
+     * The JVM imposes a similar requirement on {@code invokespecial} instruction,
+     * that the receiver argument must match both the resolved method <em>and</em>
+     * the current class.  Again, this requirement is enforced by narrowing the
+     * type of the leading parameter to the resulting method handle.
+     * (See the Java Virtual Machine Specification, section 4.10.1.9.)
+     * <p>
+     * The JVM represents constructors and static initializer blocks as internal methods
+     * with special names ({@code "<init>"} and {@code "<clinit>"}).
+     * The internal syntax of invocation instructions allows them to refer to such internal
+     * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
+     * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
+     * <p>
      * In some cases, access between nested classes is obtained by the Java compiler by creating
      * an wrapper method to access a private method of another class
      * in the same top-level declaration.
@@ -313,6 +371,43 @@
      * which can transform a lookup on {@code C.E} into one on any of those other
      * classes, without special elevation of privilege.
      * <p>
+     * The accesses permitted to a given lookup object may be limited,
+     * according to its set of {@link #lookupModes lookupModes},
+     * to a subset of members normally accessible to the lookup class.
+     * For example, the {@link MethodHandles#publicLookup publicLookup}
+     * method produces a lookup object which is only allowed to access
+     * public members in public classes.
+     * The caller sensitive method {@link MethodHandles#lookup lookup}
+     * produces a lookup object with full capabilities relative to
+     * its caller class, to emulate all supported bytecode behaviors.
+     * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
+     * with fewer access modes than the original lookup object.
+     *
+     * <p style="font-size:smaller;">
+     * <a name="privacc"></a>
+     * <em>Discussion of private access:</em>
+     * We say that a lookup has <em>private access</em>
+     * if its {@linkplain #lookupModes lookup modes}
+     * include the possibility of accessing {@code private} members.
+     * As documented in the relevant methods elsewhere,
+     * only lookups with private access possess the following capabilities:
+     * <ul style="font-size:smaller;">
+     * <li>access private fields, methods, and constructors of the lookup class
+     * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
+     *     such as {@code Class.forName}
+     * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
+     * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
+     *     for classes accessible to the lookup class
+     * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
+     *     within the same package member
+     * </ul>
+     * <p style="font-size:smaller;">
+     * Each of these permissions is a consequence of the fact that a lookup object
+     * with private access can be securely traced back to an originating class,
+     * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
+     * can be reliably determined and emulated by method handles.
+     *
+     * <h1><a name="secmgr"></a>Security manager interactions</h1>
      * Although bytecode instructions can only refer to classes in
      * a related class loader, this API can search for methods in any
      * class, as long as a reference to its {@code Class} object is
@@ -325,16 +420,6 @@
      * and the Core Reflection API
      * (as found on {@link java.lang.Class Class}).
      * <p>
-     * Access checks only apply to named and reflected methods,
-     * constructors, and fields.
-     * Other method handle creation methods, such as
-     * {@link MethodHandle#asType MethodHandle.asType},
-     * do not require any access checks, and are done
-     * with static methods of {@link MethodHandles},
-     * independently of any {@code Lookup} object.
-     *
-     * <h1>Security manager interactions</h1>
-     * <a name="secmgr"></a>
      * If a security manager is present, member lookups are subject to
      * additional checks.
      * From one to three calls are made to the security manager.
@@ -347,26 +432,79 @@
      * member is actually defined.
      * The value {@code lookc} is defined as <em>not present</em>
      * if the current lookup object does not have
-     * {@linkplain java.lang.invoke.MethodHandles.Lookup#PRIVATE private access}.
+     * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
      * The calls are made according to the following rules:
      * <ul>
-     * <li>If {@code lookc} is not present, or if its class loader is not
+     * <li><b>Step 1:</b>
+     *     If {@code lookc} is not present, or if its class loader is not
      *     the same as or an ancestor of the class loader of {@code refc},
      *     then {@link SecurityManager#checkPackageAccess
      *     smgr.checkPackageAccess(refcPkg)} is called,
      *     where {@code refcPkg} is the package of {@code refc}.
-     * <li>If the retrieved member is not public and
+     * <li><b>Step 2:</b>
+     *     If the retrieved member is not public and
      *     {@code lookc} is not present, then
      *     {@link SecurityManager#checkPermission smgr.checkPermission}
      *     with {@code RuntimePermission("accessDeclaredMembers")} is called.
-     * <li>If the retrieved member is not public,
+     * <li><b>Step 3:</b>
+     *     If the retrieved member is not public,
+     *     and if {@code lookc} is not present,
      *     and if {@code defc} and {@code refc} are different,
      *     then {@link SecurityManager#checkPackageAccess
      *     smgr.checkPackageAccess(defcPkg)} is called,
      *     where {@code defcPkg} is the package of {@code defc}.
      * </ul>
+     * Security checks are performed after other access checks have passed.
+     * Therefore, the above rules presuppose a member that is public,
+     * or else that is being accessed from a lookup class that has
+     * rights to access the member.
+     *
+     * <h1><a name="callsens"></a>Caller sensitive methods</h1>
+     * A small number of Java methods have a special property called caller sensitivity.
+     * A <em>caller-sensitive</em> method can behave differently depending on the
+     * identity of its immediate caller.
+     * <p>
+     * If a method handle for a caller-sensitive method is requested,
+     * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
+     * but they take account of the lookup class in a special way.
+     * The resulting method handle behaves as if it were called
+     * from an instruction contained in the lookup class,
+     * so that the caller-sensitive method detects the lookup class.
+     * (By contrast, the invoker of the method handle is disregarded.)
+     * Thus, in the case of caller-sensitive methods,
+     * different lookup classes may give rise to
+     * differently behaving method handles.
+     * <p>
+     * In cases where the lookup object is
+     * {@link MethodHandles#publicLookup() publicLookup()},
+     * or some other lookup object without
+     * <a href="MethodHandles.Lookup.html#privacc">private access</a>,
+     * the lookup class is disregarded.
+     * In such cases, no caller-sensitive method handle can be created,
+     * access is forbidden, and the lookup fails with an
+     * {@code IllegalAccessException}.
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * For example, the caller-sensitive method
+     * {@link java.lang.Class#forName(String) Class.forName(x)}
+     * can return varying classes or throw varying exceptions,
+     * depending on the class loader of the class that calls it.
+     * A public lookup of {@code Class.forName} will fail, because
+     * there is no reasonable way to determine its bytecode behavior.
+     * <p style="font-size:smaller;">
+     * If an application caches method handles for broad sharing,
+     * it should use {@code publicLookup()} to create them.
+     * If there is a lookup of {@code Class.forName}, it will fail,
+     * and the application must take appropriate action in that case.
+     * It may be that a later lookup, perhaps during the invocation of a
+     * bootstrap method, can incorporate the specific identity
+     * of the caller, making the method accessible.
+     * <p style="font-size:smaller;">
+     * The function {@code MethodHandles.lookup} is caller sensitive
+     * so that there can be a secure foundation for lookups.
+     * Nearly all other methods in the JSR 292 API rely on lookup
+     * objects to check access requests.
      */
-    // FIXME in MR1: clarify that the bytecode behavior of a caller-ID method (like Class.forName) is relative to the lookupClass used to create the method handle, not the dynamic caller of the method handle
     public static final
     class Lookup {
         /** The class on behalf of whom the lookup is being performed. */
@@ -592,13 +730,23 @@
          * (Since static methods do not take receivers, there is no
          * additional receiver argument inserted into the method handle type,
          * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
-         * The method and all its argument types must be accessible to the lookup class.
-         * If the method's class has not yet been initialized, that is done
-         * immediately, before the method handle is returned.
+         * The method and all its argument types must be accessible to the lookup object.
          * <p>
          * The returned method handle will have
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If the returned method handle is invoked, the method's class will
+         * be initialized, if it has not already been initialized.
+         * <p><b>Example:</b>
+         * <p><blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
+  "asList", methodType(List.class, Object[].class));
+assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
+         * }</pre></blockquote>
          * @param refc the class from which the method is accessed
          * @param name the name of the method
          * @param type the type of the method
@@ -615,7 +763,6 @@
         public
         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
-            checkSecurityManager(refc, method);
             return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method));
         }
 
@@ -623,7 +770,7 @@
          * Produces a method handle for a virtual method.
          * The type of the method handle will be that of the method,
          * with the receiver type (usually {@code refc}) prepended.
-         * The method and all its argument types must be accessible to the lookup class.
+         * The method and all its argument types must be accessible to the lookup object.
          * <p>
          * When called, the handle will treat the first argument as a receiver
          * and dispatch on the receiver's type to determine which method
@@ -640,7 +787,7 @@
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the method's variable arity modifier bit ({@code 0x0080}) is set.
          * <p>
-         * Because of the general equivalence between {@code invokevirtual}
+         * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
          * instructions and method handles produced by {@code findVirtual},
          * if the class is {@code MethodHandle} and the name string is
          * {@code invokeExact} or {@code invoke}, the resulting
@@ -649,6 +796,34 @@
          * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
          * with the same {@code type} argument.
          *
+         * <b>Example:</b>
+         * <p><blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_concat = publicLookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
+  "hashCode", methodType(int.class));
+MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
+  "hashCode", methodType(int.class));
+assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
+assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
+assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
+// interface method:
+MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
+  "subSequence", methodType(CharSequence.class, int.class, int.class));
+assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
+// constructor "internal method" must be accessed differently:
+MethodType MT_newString = methodType(void.class); //()V for new String()
+try { assertEquals("impossible", lookup()
+        .findVirtual(String.class, "<init>", MT_newString));
+ } catch (NoSuchMethodException ex) { } // OK
+MethodHandle MH_newString = publicLookup()
+  .findConstructor(String.class, MT_newString);
+assertEquals("", (String) MH_newString.invokeExact());
+         * }</pre></blockquote>
+         *
          * @param refc the class or interface from which the method is accessed
          * @param name the name of the method
          * @param type the type of the method, with the receiver argument omitted
@@ -669,7 +844,6 @@
             }
             byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
             MemberName method = resolveOrFail(refKind, refc, name, type);
-            checkSecurityManager(refc, method);
             return getDirectMethod(refKind, refc, method, findBoundCallerClass(method));
         }
         private MethodHandle findVirtualForMH(String name, MethodType type) {
@@ -687,16 +861,35 @@
          * the constructor of the specified type.
          * The parameter types of the method handle will be those of the constructor,
          * while the return type will be a reference to the constructor's class.
-         * The constructor and all its argument types must be accessible to the lookup class.
-         * If the constructor's class has not yet been initialized, that is done
-         * immediately, before the method handle is returned.
+         * The constructor and all its argument types must be accessible to the lookup object.
          * <p>
-         * Note:  The requested type must have a return type of {@code void}.
-         * This is consistent with the JVM's treatment of constructor type descriptors.
+         * The requested type must have a return type of {@code void}.
+         * (This is consistent with the JVM's treatment of constructor type descriptors.)
          * <p>
          * The returned method handle will have
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If the returned method handle is invoked, the constructor's class will
+         * be initialized, if it has not already been initialized.
+         * <p><b>Example:</b>
+         * <p><blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle MH_newArrayList = publicLookup().findConstructor(
+  ArrayList.class, methodType(void.class, Collection.class));
+Collection orig = Arrays.asList("x", "y");
+Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
+assert(orig != copy);
+assertEquals(orig, copy);
+// a variable-arity constructor:
+MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
+  ProcessBuilder.class, methodType(void.class, String[].class));
+ProcessBuilder pb = (ProcessBuilder)
+  MH_newProcessBuilder.invoke("x", "y", "z");
+assertEquals("[x, y, z]", pb.command().toString());
+         * }</pre></blockquote>
          * @param refc the class or interface from which the method is accessed
          * @param type the type of the method, with the receiver argument omitted, and a void return type
          * @return the desired method handle
@@ -711,31 +904,68 @@
         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             String name = "<init>";
             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
-            checkSecurityManager(refc, ctor);
             return getDirectConstructor(refc, ctor);
         }
 
         /**
-         * Produces an early-bound method handle for a virtual method,
-         * as if called from an {@code invokespecial}
-         * instruction from {@code caller}.
+         * Produces an early-bound method handle for a virtual method.
+         * It will bypass checks for overriding methods on the receiver,
+         * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
+         * instruction from within the explicitly specified {@code specialCaller}.
          * The type of the method handle will be that of the method,
-         * with a suitably restricted receiver type (such as {@code caller}) prepended.
+         * with a suitably restricted receiver type prepended.
+         * (The receiver type will be {@code specialCaller} or a subtype.)
          * The method and all its argument types must be accessible
-         * to the caller.
+         * to the lookup object.
          * <p>
-         * When called, the handle will treat the first argument as a receiver,
-         * but will not dispatch on the receiver's type.
-         * (This direct invocation action is identical with that performed by an
-         * {@code invokespecial} instruction.)
-         * <p>
-         * If the explicitly specified caller class is not identical with the
-         * lookup class, or if this lookup object does not have private access
+         * Before method resolution,
+         * if the explicitly specified caller class is not identical with the
+         * lookup class, or if this lookup object does not have
+         * <a href="MethodHandles.Lookup.html#privacc">private access</a>
          * privileges, the access fails.
          * <p>
          * The returned method handle will have
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p style="font-size:smaller;">
+         * <em>(Note:  JVM internal methods named {@code "<init>"} are not visible to this API,
+         * even though the {@code invokespecial} instruction can refer to them
+         * in special circumstances.  Use {@link #findConstructor findConstructor}
+         * to access instance initialization methods in a safe manner.)</em>
+         * <p><b>Example:</b>
+         * <p><blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+static class Listie extends ArrayList {
+  public String toString() { return "[wee Listie]"; }
+  static Lookup lookup() { return MethodHandles.lookup(); }
+}
+...
+// no access to constructor via invokeSpecial:
+MethodHandle MH_newListie = Listie.lookup()
+  .findConstructor(Listie.class, methodType(void.class));
+Listie l = (Listie) MH_newListie.invokeExact();
+try { assertEquals("impossible", Listie.lookup().findSpecial(
+        Listie.class, "<init>", methodType(void.class), Listie.class));
+ } catch (NoSuchMethodException ex) { } // OK
+// access to super and self methods via invokeSpecial:
+MethodHandle MH_super = Listie.lookup().findSpecial(
+  ArrayList.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_this = Listie.lookup().findSpecial(
+  Listie.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_duper = Listie.lookup().findSpecial(
+  Object.class, "toString" , methodType(String.class), Listie.class);
+assertEquals("[]", (String) MH_super.invokeExact(l));
+assertEquals(""+l, (String) MH_this.invokeExact(l));
+assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
+try { assertEquals("inaccessible", Listie.lookup().findSpecial(
+        String.class, "toString", methodType(String.class), Listie.class));
+ } catch (IllegalAccessException ex) { } // OK
+Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
+assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
+         * }</pre></blockquote>
+         *
          * @param refc the class or interface from which the method is accessed
          * @param name the name of the method (which must not be "&lt;init&gt;")
          * @param type the type of the method, with the receiver argument omitted
@@ -754,7 +984,6 @@
             checkSpecialCaller(specialCaller);
             Lookup specialLookup = this.in(specialCaller);
             MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
-            checkSecurityManager(refc, method);
             return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
         }
 
@@ -777,7 +1006,6 @@
          */
         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             MemberName field = resolveOrFail(REF_getField, refc, name, type);
-            checkSecurityManager(refc, field);
             return getDirectField(REF_getField, refc, field);
         }
 
@@ -800,7 +1028,6 @@
          */
         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             MemberName field = resolveOrFail(REF_putField, refc, name, type);
-            checkSecurityManager(refc, field);
             return getDirectField(REF_putField, refc, field);
         }
 
@@ -810,6 +1037,9 @@
          * value type.
          * The method handle will take no arguments.
          * Access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
          * @param refc the class or interface from which the method is accessed
          * @param name the field's name
          * @param type the field's type
@@ -822,7 +1052,6 @@
          */
         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
-            checkSecurityManager(refc, field);
             return getDirectField(REF_getStatic, refc, field);
         }
 
@@ -832,6 +1061,9 @@
          * The method handle will take a single
          * argument, of the field's value type, the value to be stored.
          * Access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
          * @param refc the class or interface from which the method is accessed
          * @param name the field's name
          * @param type the field's type
@@ -844,7 +1076,6 @@
          */
         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
-            checkSecurityManager(refc, field);
             return getDirectField(REF_putStatic, refc, field);
         }
 
@@ -852,7 +1083,7 @@
          * Produces an early-bound method handle for a non-static method.
          * The receiver must have a supertype {@code defc} in which a method
          * of the given name and type is accessible to the lookup class.
-         * The method and all its argument types must be accessible to the lookup class.
+         * The method and all its argument types must be accessible to the lookup object.
          * The type of the method handle will be that of the method,
          * without any insertion of an additional receiver parameter.
          * The given receiver will be bound into the method handle,
@@ -867,17 +1098,17 @@
          * the given receiver value will be bound to it.)
          * <p>
          * This is equivalent to the following code:
-         * <blockquote><pre>
+         * <blockquote><pre>{@code
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
 ...
-MethodHandle mh0 = lookup().{@link #findVirtual findVirtual}(defc, name, type);
-MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
+MethodHandle mh0 = lookup().findVirtual(defc, name, type);
+MethodHandle mh1 = mh0.bindTo(receiver);
 MethodType mt1 = mh1.type();
 if (mh0.isVarargsCollector())
   mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
 return mh1;
-         * </pre></blockquote>
+         * }</pre></blockquote>
          * where {@code defc} is either {@code receiver.getClass()} or a super
          * type of that class, in which the requested method is accessible
          * to the lookup class.
@@ -893,17 +1124,19 @@
          * @exception SecurityException if a security manager is present and it
          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
          * @throws NullPointerException if any argument is null
+         * @see MethodHandle#bindTo
+         * @see #findVirtual
          */
         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             Class<? extends Object> refc = receiver.getClass(); // may get NPE
             MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
-            checkSecurityManager(refc, method);
             MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
             return mh.bindReceiver(receiver).setVarargs(method);
         }
 
         /**
-         * Makes a direct method handle to <i>m</i>, if the lookup class has permission.
+         * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
+         * to <i>m</i>, if the lookup class has permission.
          * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
          * If <i>m</i> is virtual, overriding is respected on every call.
          * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
@@ -916,6 +1149,10 @@
          * The returned method handle will have
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the method's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If <i>m</i> is static, and
+         * if the returned method handle is invoked, the method's class will
+         * be initialized, if it has not already been initialized.
          * @param m the reflected method
          * @return a method handle which can invoke the reflected method
          * @throws IllegalAccessException if access checking fails
@@ -934,7 +1171,7 @@
                 refKind = REF_invokeVirtual;
             assert(method.isMethod());
             Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
-            return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
+            return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
         }
         private MethodHandle unreflectForMH(Method m) {
             // these names require special lookups because they throw UnsupportedOperationException
@@ -946,13 +1183,21 @@
         /**
          * Produces a method handle for a reflected method.
          * It will bypass checks for overriding methods on the receiver,
-         * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
+         * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
+         * instruction from within the explicitly specified {@code specialCaller}.
          * The type of the method handle will be that of the method,
-         * with the special caller type prepended (and <em>not</em> the receiver of the method).
+         * with a suitably restricted receiver type prepended.
+         * (The receiver type will be {@code specialCaller} or a subtype.)
          * If the method's {@code accessible} flag is not set,
          * access checking is performed immediately on behalf of the lookup class,
          * as if {@code invokespecial} instruction were being linked.
          * <p>
+         * Before method resolution,
+         * if the explicitly specified caller class is not identical with the
+         * lookup class, or if this lookup object does not have
+         * <a href="MethodHandles.Lookup.html#privacc">private access</a>
+         * privileges, the access fails.
+         * <p>
          * The returned method handle will have
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the method's variable arity modifier bit ({@code 0x0080}) is set.
@@ -970,7 +1215,7 @@
             MemberName method = new MemberName(m, true);
             assert(method.isMethod());
             // ignore m.isAccessible:  this is a new kind of access
-            return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method));
+            return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method));
         }
 
         /**
@@ -987,6 +1232,9 @@
          * The returned method handle will have
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
+         * <p>
+         * If the returned method handle is invoked, the constructor's class will
+         * be initialized, if it has not already been initialized.
          * @param c the reflected constructor
          * @return a method handle which can invoke the reflected constructor
          * @throws IllegalAccessException if access checking fails
@@ -994,12 +1242,11 @@
          *                                is set and {@code asVarargsCollector} fails
          * @throws NullPointerException if the argument is null
          */
-        @SuppressWarnings("rawtypes")  // Will be Constructor<?> after JSR 292 MR
-        public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
+        public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
             MemberName ctor = new MemberName(c);
             assert(ctor.isConstructor());
             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
-            return lookup.getDirectConstructor(ctor.getDeclaringClass(), ctor);
+            return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
         }
 
         /**
@@ -1011,6 +1258,10 @@
          * the field.
          * If the field's {@code accessible} flag is not set,
          * access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the field is static, and
+         * if the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
          * @param f the reflected field
          * @return a method handle which can load values from the reflected field
          * @throws IllegalAccessException if access checking fails
@@ -1025,7 +1276,7 @@
                     ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
                     : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
             Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
-            return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
+            return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
         }
 
         /**
@@ -1037,6 +1288,10 @@
          * the field, and the value to be stored.
          * If the field's {@code accessible} flag is not set,
          * access checking is performed immediately on behalf of the lookup class.
+         * <p>
+         * If the field is static, and
+         * if the returned method handle is invoked, the field's class will
+         * be initialized, if it has not already been initialized.
          * @param f the reflected field
          * @return a method handle which can store values into the reflected field
          * @throws IllegalAccessException if access checking fails
@@ -1047,17 +1302,21 @@
         }
 
         /**
-         * Cracks a direct method handle created by this lookup object or a similar one.
+         * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
+         * created by this lookup object or a similar one.
          * Security and access checks are performed to ensure that this lookup object
          * is capable of reproducing the target method handle.
          * This means that the cracking may fail if target is a direct method handle
          * but was created by an unrelated lookup object.
+         * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
+         * and was created by a lookup object for a different class.
          * @param target a direct method handle to crack into symbolic reference components
          * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
          * @exception SecurityException if a security manager is present and it
          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
          * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
          * @exception NullPointerException if the target is {@code null}
+         * @see MethodHandleInfo
          * @since 1.8
          */
         public MethodHandleInfo revealDirect(MethodHandle target) {
@@ -1077,11 +1336,16 @@
                 refKind = REF_invokeInterface;
             // Check SM permissions and member access before cracking.
             try {
+                checkAccess(refKind, defc, member);
                 checkSecurityManager(defc, member);
-                checkAccess(refKind, defc, member);
             } catch (IllegalAccessException ex) {
                 throw new IllegalArgumentException(ex);
             }
+            if (allowedModes != TRUSTED && member.isCallerSensitive()) {
+                Class<?> callerClass = target.internalCallerClass();
+                if (!hasPrivateAccess() || callerClass != lookupClass())
+                    throw new IllegalArgumentException("method handle is caller sensitive: "+callerClass);
+            }
             // Produce the handle to the results.
             return new InfoFromMemberName(this, member, refKind);
         }
@@ -1090,24 +1354,43 @@
 
         MemberName resolveOrFail(byte refKind, Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
-            name.getClass(); type.getClass();  // NPE
+            name.getClass();  // NPE
+            type.getClass();  // NPE
             return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
                                             NoSuchFieldException.class);
         }
 
         MemberName resolveOrFail(byte refKind, Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
-            name.getClass(); type.getClass();  // NPE
+            name.getClass();  // NPE
+            type.getClass();  // NPE
+            checkMethodName(refKind, name);  // NPE check on name
             return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
                                             NoSuchMethodException.class);
         }
 
+        MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException {
+            checkSymbolicClass(member.getDeclaringClass());  // do this before attempting to resolve
+            member.getName().getClass();  // NPE
+            member.getType().getClass();  // NPE
+            return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(),
+                                            ReflectiveOperationException.class);
+        }
+
         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
+            refc.getClass();  // NPE
             Class<?> caller = lookupClassOrNull();
             if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes))
                 throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
         }
 
+        /** Check name for an illegal leading "&lt;" character. */
+        void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
+            if (name.startsWith("<") && refKind != REF_newInvokeSpecial)
+                throw new NoSuchMethodException("illegal method name: "+name);
+        }
+
+
         /**
          * Find my trustable caller class if m is a caller sensitive method.
          * If this lookup object has private access, then the caller class is the lookupClass.
@@ -1116,8 +1399,8 @@
         Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
             Class<?> callerClass = null;
             if (MethodHandleNatives.isCallerSensitive(m)) {
-                // Only full-power lookup is allowed to resolve caller-sensitive methods
-                if (isFullPowerLookup()) {
+                // Only lookups with private access are allowed to resolve caller-sensitive methods
+                if (hasPrivateAccess()) {
                     callerClass = lookupClass;
                 } else {
                     throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
@@ -1126,7 +1409,7 @@
             return callerClass;
         }
 
-        private boolean isFullPowerLookup() {
+        private boolean hasPrivateAccess() {
             return (allowedModes & PRIVATE) != 0;
         }
 
@@ -1141,22 +1424,21 @@
             if (allowedModes == TRUSTED)  return;
 
             // Step 1:
-            if (!isFullPowerLookup() ||
+            boolean fullPowerLookup = hasPrivateAccess();
+            if (!fullPowerLookup ||
                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
                 ReflectUtil.checkPackageAccess(refc);
             }
 
             // Step 2:
             if (m.isPublic()) return;
-            Class<?> defc = m.getDeclaringClass();
-            {
-                if (!isFullPowerLookup()) {
-                    smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
-                }
+            if (!fullPowerLookup) {
+                smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
             }
 
             // Step 3:
-            if (defc != refc) {
+            Class<?> defc = m.getDeclaringClass();
+            if (!fullPowerLookup && defc != refc) {
                 ReflectUtil.checkPackageAccess(defc);
             }
         }
@@ -1185,6 +1467,7 @@
             throw m.makeAccessException(message, this);
         }
 
+        /** Check public/protected/private bits on the symbolic reference class and its member. */
         void checkAccess(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
             assert(m.referenceKindIsConsistentWith(refKind) &&
                    MethodHandleNatives.refKindIsValid(refKind) &&
@@ -1192,6 +1475,26 @@
             int allowedModes = this.allowedModes;
             if (allowedModes == TRUSTED)  return;
             int mods = m.getModifiers();
+            if (Modifier.isProtected(mods) &&
+                    refKind == REF_invokeVirtual &&
+                    m.getDeclaringClass() == Object.class &&
+                    m.getName().equals("clone") &&
+                    refc.isArray()) {
+                // The JVM does this hack also.
+                // (See ClassVerifier::verify_invoke_instructions
+                // and LinkResolver::check_method_accessability.)
+                // Because the JVM does not allow separate methods on array types,
+                // there is no separate method for int[].clone.
+                // All arrays simply inherit Object.clone.
+                // But for access checking logic, we make Object.clone
+                // (normally protected) appear to be public.
+                // Later on, when the DirectMethodHandle is created,
+                // its leading argument will be restricted to the
+                // requested array type.
+                // N.B. The return type is not adjusted, because
+                // that is *not* the bytecode behavior.
+                mods ^= Modifier.PROTECTED | Modifier.PUBLIC;
+            }
             if (Modifier.isFinal(mods) &&
                     MethodHandleNatives.refKindIsSetter(refKind))
                 throw m.makeAccessException("unexpected set of a final field", this);
@@ -1239,7 +1542,7 @@
         private void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
             int allowedModes = this.allowedModes;
             if (allowedModes == TRUSTED)  return;
-            if ((allowedModes & PRIVATE) == 0
+            if (!hasPrivateAccess()
                 || (specialCaller != lookupClass()
                     && !(ALLOW_NESTMATE_ACCESS &&
                          VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
@@ -1271,18 +1574,32 @@
             return mh.viewAsType(narrowType);
         }
 
+        /** Check access and get the requested method. */
         private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
-            return getDirectMethodCommon(refKind, refc, method,
-                    (refKind == REF_invokeSpecial ||
-                        (MethodHandleNatives.refKindHasReceiver(refKind) &&
-                            restrictProtectedReceiver(method))), callerClass);
+            final boolean doRestrict    = true;
+            final boolean checkSecurity = true;
+            return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
+        }
+        /** Check access and get the requested method, eliding receiver narrowing rules. */
+        private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
+            final boolean doRestrict    = false;
+            final boolean checkSecurity = true;
+            return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
         }
-        private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
-            return getDirectMethodCommon(refKind, refc, method, false, callerClass);
+        /** Check access and get the requested method, eliding security manager checks. */
+        private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
+            final boolean doRestrict    = true;
+            final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
+            return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
         }
+        /** Common code for all methods; do not call directly except from immediately above. */
         private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
+                                                   boolean checkSecurity,
                                                    boolean doRestrict, Class<?> callerClass) throws IllegalAccessException {
             checkMethod(refKind, refc, method);
+            // Optionally check with the security manager; this isn't needed for unreflect* calls.
+            if (checkSecurity)
+                checkSecurityManager(refc, method);
             assert(!method.isMethodHandleInvoke());
 
             Class<?> refcAsSuper;
@@ -1312,7 +1629,11 @@
             MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
             mh = maybeBindCaller(method, mh, callerClass);
             mh = mh.setVarargs(method);
-            if (doRestrict)
+            // Optionally narrow the receiver argument to refc using restrictReceiver.
+            if (doRestrict &&
+                   (refKind == REF_invokeSpecial ||
+                       (MethodHandleNatives.refKindHasReceiver(refKind) &&
+                           restrictProtectedReceiver(method))))
                 mh = restrictReceiver(method, mh, lookupClass());
             return mh;
         }
@@ -1322,14 +1643,29 @@
             if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
                 return mh;
             Class<?> hostClass = lookupClass;
-            if ((allowedModes & PRIVATE) == 0)  // caller must use full-power lookup
+            if (!hasPrivateAccess())  // caller must have private access
                 hostClass = callerClass;  // callerClass came from a security manager style stack walk
             MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
             // Note: caller will apply varargs after this step happens.
             return cbmh;
         }
+        /** Check access and get the requested field. */
         private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
+            final boolean checkSecurity = true;
+            return getDirectFieldCommon(refKind, refc, field, checkSecurity);
+        }
+        /** Check access and get the requested field, eliding security manager checks. */
+        private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
+            final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
+            return getDirectFieldCommon(refKind, refc, field, checkSecurity);
+        }
+        /** Common code for all fields; do not call directly except from immediately above. */
+        private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field,
+                                                  boolean checkSecurity) throws IllegalAccessException {
             checkField(refKind, refc, field);
+            // Optionally check with the security manager; this isn't needed for unreflect* calls.
+            if (checkSecurity)
+                checkSecurityManager(refc, field);
             MethodHandle mh = DirectMethodHandle.make(refc, field);
             boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
                                     restrictProtectedReceiver(field));
@@ -1337,9 +1673,24 @@
                 mh = restrictReceiver(field, mh, lookupClass());
             return mh;
         }
+        /** Check access and get the requested constructor. */
         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
+            final boolean checkSecurity = true;
+            return getDirectConstructorCommon(refc, ctor, checkSecurity);
+        }
+        /** Check access and get the requested constructor, eliding security manager checks. */
+        private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
+            final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
+            return getDirectConstructorCommon(refc, ctor, checkSecurity);
+        }
+        /** Common code for all constructors; do not call directly except from immediately above. */
+        private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
+                                                  boolean checkSecurity) throws IllegalAccessException {
             assert(ctor.isConstructor());
             checkAccess(REF_newInvokeSpecial, refc, ctor);
+            // Optionally check with the security manager; this isn't needed for unreflect* calls.
+            if (checkSecurity)
+                checkSecurityManager(refc, ctor);
             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
             return DirectMethodHandle.make(ctor).setVarargs(ctor);
         }
@@ -1348,29 +1699,75 @@
          */
         /*non-public*/
         MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException {
-            MemberName resolved = null;
-            if (type instanceof MemberName) {
-                resolved = (MemberName) type;
-                if (!resolved.isResolved())  throw new InternalError("unresolved MemberName");
-                assert(name == null || name.equals(resolved.getName()));
+            if (!(type instanceof Class || type instanceof MethodType))
+                throw new InternalError("unresolved MemberName");
+            MemberName member = new MemberName(refKind, defc, name, type);
+            MethodHandle mh = LOOKASIDE_TABLE.get(member);
+            if (mh != null) {
+                checkSymbolicClass(defc);
+                return mh;
+            }
+            MemberName resolved = resolveOrFail(refKind, member);
+            mh = getDirectMethodForConstant(refKind, defc, resolved);
+            if (mh instanceof DirectMethodHandle
+                    && canBeCached(refKind, defc, resolved)) {
+                MemberName key = mh.internalMemberName();
+                if (key != null) {
+                    key = key.asNormalOriginal();
+                }
+                if (member.equals(key)) {  // better safe than sorry
+                    LOOKASIDE_TABLE.put(key, (DirectMethodHandle) mh);
+                }
+            }
+            return mh;
+        }
+        private
+        boolean canBeCached(byte refKind, Class<?> defc, MemberName member) {
+            if (refKind == REF_invokeSpecial) {
+                return false;
             }
+            if (!Modifier.isPublic(defc.getModifiers()) ||
+                    !Modifier.isPublic(member.getDeclaringClass().getModifiers()) ||
+                    !member.isPublic() ||
+                    member.isCallerSensitive()) {
+                return false;
+            }
+            ClassLoader loader = defc.getClassLoader();
+            if (!sun.misc.VM.isSystemDomainLoader(loader)) {
+                ClassLoader sysl = ClassLoader.getSystemClassLoader();
+                boolean found = false;
+                while (sysl != null) {
+                    if (loader == sysl) { found = true; break; }
+                    sysl = sysl.getParent();
+                }
+                if (!found) {
+                    return false;
+                }
+            }
+            try {
+                MemberName resolved2 = publicLookup().resolveOrFail(refKind,
+                    new MemberName(refKind, defc, member.getName(), member.getType()));
+                checkSecurityManager(defc, resolved2);
+            } catch (ReflectiveOperationException | SecurityException ex) {
+                return false;
+            }
+            return true;
+        }
+        private
+        MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
+                throws ReflectiveOperationException {
             if (MethodHandleNatives.refKindIsField(refKind)) {
-                MemberName field = (resolved != null) ? resolved
-                        : resolveOrFail(refKind, defc, name, (Class<?>) type);
-                return getDirectField(refKind, defc, field);
+                return getDirectFieldNoSecurityManager(refKind, defc, member);
             } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
-                MemberName method = (resolved != null) ? resolved
-                        : resolveOrFail(refKind, defc, name, (MethodType) type);
-                return getDirectMethod(refKind, defc, method, lookupClass);
+                return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
             } else if (refKind == REF_newInvokeSpecial) {
-                assert(name == null || name.equals("<init>"));
-                MemberName ctor = (resolved != null) ? resolved
-                        : resolveOrFail(REF_newInvokeSpecial, defc, name, (MethodType) type);
-                return getDirectConstructor(defc, ctor);
+                return getDirectConstructorNoSecurityManager(defc, member);
             }
             // oops
-            throw new ReflectiveOperationException("bad MethodHandle constant #"+refKind+" "+name+" : "+type);
+            throw newIllegalArgumentException("bad MethodHandle constant #"+member);
         }
+
+        static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>();
     }
 
     /**
@@ -1430,22 +1827,26 @@
      * <p>
      * Before invoking its target, the invoker will spread the final array, apply
      * reference casts as necessary, and unbox and widen primitive arguments.
+     * If, when the invoker is called, the supplied array argument does
+     * not have the correct number of elements, the invoker will throw
+     * an {@link IllegalArgumentException} instead of invoking the target.
      * <p>
      * This method is equivalent to the following code (though it may be more efficient):
-     * <p><blockquote><pre>
+     * <blockquote><pre>{@code
 MethodHandle invoker = MethodHandles.invoker(type);
 int spreadArgCount = type.parameterCount() - leadingArgCount;
 invoker = invoker.asSpreader(Object[].class, spreadArgCount);
 return invoker;
-     * </pre></blockquote>
-     * <p>
+     * }</pre></blockquote>
      * This method throws no reflective or security exceptions.
      * @param type the desired target type
      * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
      * @return a method handle suitable for invoking any method handle of the given type
      * @throws NullPointerException if {@code type} is null
      * @throws IllegalArgumentException if {@code leadingArgCount} is not in
-     *                  the range from 0 to {@code type.parameterCount()} inclusive
+     *                  the range from 0 to {@code type.parameterCount()} inclusive,
+     *                  or if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
      */
     static public
     MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
@@ -1462,9 +1863,7 @@
      * an additional leading argument of type {@code MethodHandle}.
      * <p>
      * This method is equivalent to the following code (though it may be more efficient):
-     * <p><blockquote><pre>
-publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
-     * </pre></blockquote>
+     * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)}
      *
      * <p style="font-size:smaller;">
      * <em>Discussion:</em>
@@ -1479,7 +1878,7 @@
      * If spreading, collecting, or other argument transformations are required,
      * they can be applied once to the invoker {@code X} and reused on many {@code M}
      * method handle values, as long as they are compatible with the type of {@code X}.
-     * <p>
+     * <p style="font-size:smaller;">
      * <em>(Note:  The invoker method is not available via the Core Reflection API.
      * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
      * on the declared {@code invokeExact} or {@code invoke} method will raise an
@@ -1488,6 +1887,8 @@
      * This method throws no reflective or security exceptions.
      * @param type the desired target type
      * @return a method handle suitable for invoking any method handle of the given type
+     * @throws IllegalArgumentException if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
      */
     static public
     MethodHandle exactInvoker(MethodType type) {
@@ -1508,19 +1909,25 @@
      * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle},
      * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}.
      * <p>
-     * A {@linkplain MethodType#genericMethodType general method type},
+     * This method is equivalent to the following code (though it may be more efficient):
+     * {@code publicLookup().findVirtual(MethodHandle.class, "invoke", type)}
+     * <p style="font-size:smaller;">
+     * <em>Discussion:</em>
+     * A {@linkplain MethodType#genericMethodType general method type} is one which
      * mentions only {@code Object} arguments and return values.
      * An invoker for such a type is capable of calling any method handle
      * of the same arity as the general type.
-     * <p>
-     * This method is equivalent to the following code (though it may be more efficient):
-     * <p><blockquote><pre>
-publicLookup().findVirtual(MethodHandle.class, "invoke", type)
-     * </pre></blockquote>
+     * <p style="font-size:smaller;">
+     * <em>(Note:  The invoker method is not available via the Core Reflection API.
+     * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
+     * on the declared {@code invokeExact} or {@code invoke} method will raise an
+     * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
      * <p>
      * This method throws no reflective or security exceptions.
      * @param type the desired target type
      * @return a method handle suitable for invoking any method handle convertible to the given type
+     * @throws IllegalArgumentException if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
      */
     static public
     MethodHandle invoker(MethodType type) {
@@ -1801,7 +2208,7 @@
      * they will come after.
      * <p>
      * <b>Example:</b>
-     * <p><blockquote><pre>
+     * <p><blockquote><pre>{@code
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
 ...
@@ -1812,11 +2219,11 @@
 MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
 assertEquals(bigType, d0.type());
 assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p>
      * This method is also equivalent to the following code:
      * <p><blockquote><pre>
-     * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}(target, pos, valueTypes.toArray(new Class[0]))
+     * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}{@code (target, pos, valueTypes.toArray(new Class[0]))}
      * </pre></blockquote>
      * @param target the method handle to invoke after the arguments are dropped
      * @param valueTypes the type(s) of the argument(s) to drop
@@ -1859,7 +2266,7 @@
      * they will come after.
      * <p>
      * <b>Example:</b>
-     * <p><blockquote><pre>
+     * <p><blockquote><pre>{@code
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
 ...
@@ -1874,11 +2281,11 @@
 assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
 MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
 assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p>
      * This method is also equivalent to the following code:
      * <p><blockquote><pre>
-     * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
+     * {@link #dropArguments(MethodHandle,int,List) dropArguments}{@code (target, pos, Arrays.asList(valueTypes))}
      * </pre></blockquote>
      * @param target the method handle to invoke after the arguments are dropped
      * @param valueTypes the type(s) of the argument(s) to drop
@@ -1889,7 +2296,8 @@
      *                              or if the {@code valueTypes} array or any of its elements is null
      * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
      *                  or if {@code pos} is negative or greater than the arity of the target,
-     *                  or if the new method handle's type would have too many parameters
+     *                  or if the new method handle's type would have
+     *                  <a href="MethodHandle.html#maxarity">too many parameters</a>
      */
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
@@ -1923,8 +2331,8 @@
      * It is an error if there are elements of {@code filters}
      * (null or not)
      * which do not correspond to argument positions in the target.
-     * <b>Example:</b>
-     * <p><blockquote><pre>
+     * <p><b>Example:</b>
+     * <p><blockquote><pre>{@code
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
 ...
@@ -1939,15 +2347,15 @@
 assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
 MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
 assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * V target(P... p, A[i]... a[i], B... b);
      * A[i] filter[i](V[i]);
      * T adapter(P... p, V[i]... v[i], B... b) {
      *   return target(p..., f[i](v[i])..., b...);
      * }
-     * </pre></blockquote>
+     * }</pre></blockquote>
      *
      * @param target the method handle to invoke after arguments are filtered
      * @param pos the position of the first argument to filter
@@ -1957,7 +2365,9 @@
      *                              or if the {@code filters} array is null
      * @throws IllegalArgumentException if a non-null element of {@code filters}
      *          does not match a corresponding argument type of target as described above,
-     *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
+     *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
+     *          or if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
      */
     public static
     MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
@@ -1989,15 +2399,120 @@
         return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
     }
 
-    // FIXME: Make this public in M1.
-    /*non-public*/ static
-    MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle collector) {
+    /**
+     * Adapts a target method handle by pre-processing
+     * a sub-sequence of its arguments with a filter (another method handle).
+     * The pre-processed arguments are replaced by the result (if any) of the
+     * filter function.
+     * The target is then called on the modified (usually shortened) argument list.
+     * <p>
+     * If the filter returns a value, the target must accept that value as
+     * its argument in position {@code pos}, preceded and/or followed by
+     * any arguments not passed to the filter.
+     * If the filter returns void, the target must accept all arguments
+     * not passed to the filter.
+     * No arguments are reordered, and a result returned from the filter
+     * replaces (in order) the whole subsequence of arguments originally
+     * passed to the adapter.
+     * <p>
+     * The argument types (if any) of the filter
+     * replace zero or one argument types of the target, at position {@code pos},
+     * in the resulting adapted method handle.
+     * The return type of the filter (if any) must be identical to the
+     * argument type of the target at position {@code pos}, and that target argument
+     * is supplied by the return value of the filter.
+     * <p>
+     * In all cases, {@code pos} must be greater than or equal to zero, and
+     * {@code pos} must also be less than or equal to the target's arity.
+     * <p><b>Example:</b>
+     * <p><blockquote><pre>{@code
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+...
+MethodHandle deepToString = publicLookup()
+  .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+
+MethodHandle ts1 = deepToString.asCollector(String[].class, 1);
+assertEquals("[strange]", (String) ts1.invokeExact("strange"));
+
+MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
+assertEquals("[up, down]", (String) ts2.invokeExact("up", "down"));
+
+MethodHandle ts3 = deepToString.asCollector(String[].class, 3);
+MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2);
+assertEquals("[top, [up, down], strange]",
+             (String) ts3_ts2.invokeExact("top", "up", "down", "strange"));
+
+MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1);
+assertEquals("[top, [up, down], [strange]]",
+             (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange"));
+
+MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
+assertEquals("[top, [[up, down, strange], charm], bottom]",
+             (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
+     * }</pre></blockquote>
+     * <p> Here is pseudocode for the resulting adapter:
+     * <blockquote><pre>{@code
+     * T target(A...,V,C...);
+     * V filter(B...);
+     * T adapter(A... a,B... b,C... c) {
+     *   V v = filter(b...);
+     *   return target(a...,v,c...);
+     * }
+     * // and if the filter has no arguments:
+     * T target2(A...,V,C...);
+     * V filter2();
+     * T adapter2(A... a,C... c) {
+     *   V v = filter2();
+     *   return target2(a...,v,c...);
+     * }
+     * // and if the filter has a void return:
+     * T target3(A...,C...);
+     * void filter3(B...);
+     * void adapter3(A... a,B... b,C... c) {
+     *   filter3(b...);
+     *   return target3(a...,c...);
+     * }
+     * }</pre></blockquote>
+     * <p>
+     * A collection adapter {@code collectArguments(mh, 0, coll)} is equivalent to
+     * one which first "folds" the affected arguments, and then drops them, in separate
+     * steps as follows:
+     * <blockquote><pre>{@code
+     * mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2
+     * mh = MethodHandles.foldArguments(mh, coll); //step 1
+     * }</pre></blockquote>
+     * If the target method handle consumes no arguments besides than the result
+     * (if any) of the filter {@code coll}, then {@code collectArguments(mh, 0, coll)}
+     * is equivalent to {@code filterReturnValue(coll, mh)}.
+     * If the filter method handle {@code coll} consumes one argument and produces
+     * a non-void result, then {@code collectArguments(mh, N, coll)}
+     * is equivalent to {@code filterArguments(mh, N, coll)}.
+     * Other equivalences are possible but would require argument permutation.
+     *
+     * @param target the method handle to invoke after filtering the subsequence of arguments
+     * @param pos the position of the first adapter argument to pass to the filter,
+     *            and/or the target argument which receives the result of the filter
+     * @param filter method handle to call on the subsequence of arguments
+     * @return method handle which incorporates the specified argument subsequence filtering logic
+     * @throws NullPointerException if either argument is null
+     * @throws IllegalArgumentException if the return type of {@code filter}
+     *          is non-void and is not the same as the {@code pos} argument of the target,
+     *          or if {@code pos} is not between 0 and the target's arity, inclusive,
+     *          or if the resulting method handle's type would have
+     *          <a href="MethodHandle.html#maxarity">too many parameters</a>
+     * @see MethodHandles#foldArguments
+     * @see MethodHandles#filterArguments
+     * @see MethodHandles#filterReturnValue
+     */
+    public static
+    MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter) {
         MethodType targetType = target.type();
-        MethodType filterType = collector.type();
+        MethodType filterType = filter.type();
         if (filterType.returnType() != void.class &&
             filterType.returnType() != targetType.parameterType(pos))
             throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
-        return MethodHandleImpl.makeCollectArguments(target, collector, pos, false);
+        return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
     }
 
     /**
@@ -2014,8 +2529,8 @@
      * in the resulting adapted method handle.
      * The argument type of the filter (if any) must be identical to the
      * return type of the target.
-     * <b>Example:</b>
-     * <p><blockquote><pre>
+     * <p><b>Example:</b>
+     * <p><blockquote><pre>{@code
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
 ...
@@ -2026,9 +2541,9 @@
 System.out.println((String) cat.invokeExact("x", "y")); // xy
 MethodHandle f0 = filterReturnValue(cat, length);
 System.out.println((int) f0.invokeExact("x", "y")); // 2
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * V target(A...);
      * T filter(V);
      * T adapter(A... a) {
@@ -2049,7 +2564,7 @@
      *   V v = target3(a...);
      *   filter3(v);
      * }
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * @param target the method handle to invoke before filtering the return value
      * @param filter method handle to call on the return value
      * @return method handle which incorporates the specified return value filtering logic
@@ -2105,8 +2620,8 @@
      * consider using {@link MethodHandle#asCollector asCollector} instead, since those
      * arguments will not need to be live on the stack on entry to the
      * target.)
-     * <b>Example:</b>
-     * <p><blockquote><pre>
+     * <p><b>Example:</b>
+     * <p><blockquote><pre>{@code
 import static java.lang.invoke.MethodHandles.*;
 import static java.lang.invoke.MethodType.*;
 ...
@@ -2119,9 +2634,9 @@
 MethodHandle catTrace = foldArguments(cat, trace);
 // also prints "boo":
 assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * // there are N arguments in A...
      * T target(V, A[N]..., B...);
      * V combiner(A...);
@@ -2136,7 +2651,7 @@
      *   combiner2(a...);
      *   return target2(a..., b...);
      * }
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * @param target the method handle to invoke after arguments are combined
      * @param combiner method handle to call initially on the incoming arguments
      * @return method handle which incorporates the specified argument folding logic
@@ -2179,7 +2694,7 @@
      * of the test must be boolean, and the test is allowed
      * to have fewer arguments than the other two method handles.
      * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * boolean test(A...);
      * T target(A...,B...);
      * T fallback(A...,B...);
@@ -2189,7 +2704,7 @@
      *   else
      *     return fallback(a..., b...);
      * }
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * Note that the test arguments ({@code a...} in the pseudocode) cannot
      * be modified by execution of the test, and so are passed unchanged
      * from the caller to the target or fallback as appropriate.
@@ -2241,7 +2756,7 @@
      * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
      * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
      * <p> Here is pseudocode for the resulting adapter:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * T target(A..., B...);
      * T handler(ExType, A...);
      * T adapter(A... a, B... b) {
@@ -2251,7 +2766,7 @@
      *     return handler(ex, a...);
      *   }
      * }
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * Note that the saved arguments ({@code a...} in the pseudocode) cannot
      * be modified by execution of the target, and so are passed unchanged
      * from the caller to the handler, if the handler is invoked.
--- a/src/share/classes/java/lang/invoke/MethodType.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodType.java	Tue Oct 08 14:57:32 2013 -0700
@@ -77,7 +77,8 @@
  * A method type may be loaded by an {@code ldc} instruction which refers
  * to a suitable {@code CONSTANT_MethodType} constant pool entry.
  * The entry refers to a {@code CONSTANT_Utf8} spelling for the descriptor string.
- * For more details, see the <a href="package-summary.html#mtcon">package summary</a>.
+ * (For full details on method type constants,
+ * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
  * <p>
  * When the JVM materializes a {@code MethodType} from a descriptor string,
  * all classes named in the descriptor must be accessible, and will be loaded.
@@ -94,9 +95,9 @@
     private final Class<?>[] ptypes;
 
     // The remaining fields are caches of various sorts:
-    private MethodTypeForm form; // erased form, plus cached data about primitives
-    private MethodType wrapAlt;  // alternative wrapped/unwrapped version
-    private Invokers invokers;   // cache of handy higher-order adapters
+    private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
+    private @Stable MethodType wrapAlt;  // alternative wrapped/unwrapped version
+    private @Stable Invokers invokers;   // cache of handy higher-order adapters
 
     /**
      * Check the given parameters for validity and store them into the final fields.
@@ -940,10 +941,10 @@
      * Instead, the return type and parameter type arrays are written directly
      * from the {@code writeObject} method, using two calls to {@code s.writeObject}
      * as follows:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
 s.writeObject(this.returnType());
 s.writeObject(this.parameterArray());
-     * </pre></blockquote>
+     * }</pre></blockquote>
      * <p>
      * The deserialized field values are checked as if they were
      * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
--- a/src/share/classes/java/lang/invoke/MethodTypeForm.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodTypeForm.java	Tue Oct 08 14:57:32 2013 -0700
@@ -28,6 +28,7 @@
 import sun.invoke.util.Wrapper;
 import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
+ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
 
 /**
  * Shared information for a group of method types, which differ
@@ -51,12 +52,13 @@
     final MethodType basicType;         // the canonical erasure, with primitives simplified
 
     // Cached adapter information:
-    /*lazy*/ MethodHandle genericInvoker; // JVM hook for inexact invoke
-    /*lazy*/ MethodHandle basicInvoker;   // cached instance of MH.invokeBasic
-    /*lazy*/ MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction
+    @Stable String typeString;           // argument type signature characters
+    @Stable MethodHandle genericInvoker; // JVM hook for inexact invoke
+    @Stable MethodHandle basicInvoker;   // cached instance of MH.invokeBasic
+    @Stable MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction
 
     // Cached lambda form information, for basic types only:
-    final LambdaForm[] lambdaForms;
+    final @Stable LambdaForm[] lambdaForms;
     // Indexes into lambdaForms:
     static final int
             LF_INVVIRTUAL     =  0,  // DMH invokeVirtual
@@ -73,7 +75,8 @@
             LF_GEN_LINKER     = 11,
             LF_GEN_INVOKER    = 12,
             LF_CS_LINKER      = 13,  // linkToCallSite_CS
-            LF_LIMIT          = 14;
+            LF_MH_LINKER      = 14,  // linkToCallSite_MH
+            LF_LIMIT          = 15;
 
     public MethodType erasedType() {
         return erasedType;
@@ -96,11 +99,24 @@
         assert(erasedType == basicType) : "erasedType: " + erasedType + " != basicType: " + basicType;  // primitives must be flattened also
         MethodHandle invoker = basicInvoker;
         if (invoker != null)  return invoker;
-        invoker = basicType.invokers().makeBasicInvoker();
+        invoker = DirectMethodHandle.make(invokeBasicMethod(basicType));
         basicInvoker = invoker;
         return invoker;
     }
 
+    // This next one is called from LambdaForm.NamedFunction.<init>.
+    /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) {
+        assert(basicType == basicType.basicType());
+        try {
+            // Do approximately the same as this public API call:
+            //   Lookup.findVirtual(MethodHandle.class, name, type);
+            // But bypass access and corner case checks, since we know exactly what we need.
+            return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, "invokeBasic", basicType);
+         } catch (ReflectiveOperationException ex) {
+            throw newInternalError("JVM cannot find invoker for "+basicType, ex);
+        }
+    }
+
     /**
      * Build an MTF for a given type, which must have all references erased to Object.
      * This MTF will stand for that type and all un-erased variations.
--- a/src/share/classes/java/lang/invoke/MutableCallSite.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MutableCallSite.java	Tue Oct 08 14:57:32 2013 -0700
@@ -38,7 +38,7 @@
  * Here is an example of a mutable call site which introduces a
  * state variable into a method handle chain.
  * <!-- JavaDocExamplesTest.testMutableCallSite -->
- * <blockquote><pre>
+ * <blockquote><pre>{@code
 MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
 MethodHandle MH_name = name.dynamicInvoker();
 MethodType MT_str1 = MethodType.methodType(String.class);
@@ -50,10 +50,10 @@
 name.setTarget(MethodHandles.constant(String.class, "Fred"));
 assertEquals("FRED", (String) worker1.invokeExact());
 // (mutation can be continued indefinitely)
- * </pre></blockquote>
+ * }</pre></blockquote>
  * <p>
  * The same call site may be used in several places at once.
- * <blockquote><pre>
+ * <blockquote><pre>{@code
 MethodType MT_str2 = MethodType.methodType(String.class, String.class);
 MethodHandle MH_cat = lookup().findVirtual(String.class,
   "concat", methodType(String.class, String.class));
@@ -63,7 +63,7 @@
 name.setTarget(MethodHandles.constant(String.class, "Wilma"));
 assertEquals("WILMA", (String) worker1.invokeExact());
 assertEquals("Wilma, dear?", (String) worker2.invokeExact());
- * </pre></blockquote>
+ * }</pre></blockquote>
  * <p>
  * <em>Non-synchronization of target values:</em>
  * A write to a mutable call site's target does not force other threads
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/invoke/Stable.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,73 @@
+/*
+ * 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 java.lang.invoke;
+
+import java.lang.annotation.*;
+
+/**
+ * A field may be annotated as stable if all of its component variables
+ * changes value at most once.
+ * A field's value counts as its component value.
+ * If the field is typed as an array, then all the non-null components
+ * of the array, of depth up to the rank of the field's array type,
+ * also count as component values.
+ * By extension, any variable (either array or field) which has annotated
+ * as stable is called a stable variable, and its non-null or non-zero
+ * value is called a stable value.
+ * <p>
+ * Since all fields begin with a default value of null for references
+ * (resp., zero for primitives), it follows that this annotation indicates
+ * that the first non-null (resp., non-zero) value stored in the field
+ * will never be changed.
+ * <p>
+ * If the field is not of an array type, there are no array elements,
+ * then the value indicated as stable is simply the value of the field.
+ * If the dynamic type of the field value is an array but the static type
+ * is not, the components of the array are <em>not</em> regarded as stable.
+ * <p>
+ * If the field is an array type, then both the field value and
+ * all the components of the field value (if the field value is non-null)
+ * are indicated to be stable.
+ * If the field type is an array type with rank {@code N &gt; 1},
+ * then each component of the field value (if the field value is non-null),
+ * is regarded as a stable array of rank {@code N-1}.
+ * <p>
+ * Fields which are declared {@code final} may also be annotated as stable.
+ * Since final fields already behave as stable values, such an annotation
+ * indicates no additional information, unless the type of the field is
+ * an array type.
+ * <p>
+ * It is (currently) undefined what happens if a field annotated as stable
+ * is given a third value.  In practice, if the JVM relies on this annotation
+ * to promote a field reference to a constant, it may be that the Java memory
+ * model would appear to be broken, if such a constant (the second value of the field)
+ * is used as the value of the field even after the field value has changed.
+ */
+/* package-private */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Stable {
+}
--- a/src/share/classes/java/lang/invoke/SwitchPoint.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/invoke/SwitchPoint.java	Tue Oct 08 14:57:32 2013 -0700
@@ -55,7 +55,7 @@
  * At that point {@code guardWithTest} may ignore {@code T} and return {@code F}.
  * <p>
  * Here is an example of a switch point in action:
- * <blockquote><pre>
+ * <blockquote><pre>{@code
 MethodHandle MH_strcat = MethodHandles.lookup()
     .findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class));
 SwitchPoint spt = new SwitchPoint();
@@ -68,7 +68,7 @@
 SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
 assert(spt.hasBeenInvalidated());
 assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));
- * </pre></blockquote>
+ * }</pre></blockquote>
  * <p style="font-size:smaller;">
  * <em>Discussion:</em>
  * Switch points are useful without subclassing.  They may also be subclassed.
@@ -82,7 +82,7 @@
  * <em>Implementation Note:</em>
  * A switch point behaves as if implemented on top of {@link MutableCallSite},
  * approximately as follows:
- * <blockquote><pre>
+ * <blockquote><pre>{@code
 public class SwitchPoint {
   private static final MethodHandle
     K_true  = MethodHandles.constant(boolean.class, true),
@@ -106,7 +106,7 @@
     MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
   }
 }
- * </pre></blockquote>
+ * }</pre></blockquote>
  * @author Remi Forax, JSR 292 EG
  */
 public class SwitchPoint {
--- a/src/share/classes/java/lang/reflect/AnnotatedArrayType.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/AnnotatedArrayType.java	Tue Oct 08 14:57:32 2013 -0700
@@ -27,17 +27,18 @@
 
 
 /**
- * AnnotatedArrayType represents the use of an array type, whose component
- * type may itself represent the annotated use of a type.
+ * {@code AnnotatedArrayType} represents the potentially annotated use of an
+ * array type, whose component type may itself represent the annotated use of a
+ * type.
  *
  * @since 1.8
  */
 public interface AnnotatedArrayType extends AnnotatedType {
 
     /**
-     * Returns the annotated generic component type of this array type.
+     * Returns the potentially annotated generic component type of this array type.
      *
-     * @return the annotated generic component type of this array type
+     * @return the potentially annotated generic component type of this array type
      */
     AnnotatedType  getAnnotatedGenericComponentType();
 }
--- a/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java	Tue Oct 08 14:57:32 2013 -0700
@@ -26,17 +26,18 @@
 package java.lang.reflect;
 
 /**
- * AnnotatedParameterizedType represents the use of a parameterized type,
- * whose type arguments may themselves represent annotated uses of types.
+ * {@code AnnotatedParameterizedType} represents the potentially annotated use
+ * of a parameterized type, whose type arguments may themselves represent
+ * annotated uses of types.
  *
  * @since 1.8
  */
 public interface AnnotatedParameterizedType extends AnnotatedType {
 
     /**
-     * Returns the annotated actual type arguments of this parameterized type.
+     * Returns the potentially annotated actual type arguments of this parameterized type.
      *
-     * @return the annotated actual type arguments of this parameterized type
+     * @return the potentially annotated actual type arguments of this parameterized type
      */
     AnnotatedType[] getAnnotatedActualTypeArguments();
 }
--- a/src/share/classes/java/lang/reflect/AnnotatedType.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/AnnotatedType.java	Tue Oct 08 14:57:32 2013 -0700
@@ -26,10 +26,10 @@
 package java.lang.reflect;
 
 /**
- * AnnotatedType represents the annotated use of a type in the program
- * currently running in this VM. The use may be of any type in the Java
- * programming language, including an array type, a parameterized type, a type
- * variable, or a wildcard type.
+ * {@code AnnotatedType} represents the potentially annotated use of a type in
+ * the program currently running in this VM. The use may be of any type in the
+ * Java programming language, including an array type, a parameterized type, a
+ * type variable, or a wildcard type.
  *
  * @since 1.8
  */
--- a/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java	Tue Oct 08 14:57:32 2013 -0700
@@ -26,18 +26,18 @@
 package java.lang.reflect;
 
 /**
- * AnnotatedTypeVariable represents the use of a type variable, whose
- * declaration may have bounds which themselves represent annotated uses of
- * types.
+ * {@code AnnotatedTypeVariable} represents the potentially annotated use of a
+ * type variable, whose declaration may have bounds which themselves represent
+ * annotated uses of types.
  *
  * @since 1.8
  */
 public interface AnnotatedTypeVariable extends AnnotatedType {
 
     /**
-     * Returns the annotated bounds of this type variable.
+     * Returns the potentially annotated bounds of this type variable.
      *
-     * @return the annotated bounds of this type variable
+     * @return the potentially annotated bounds of this type variable
      */
     AnnotatedType[] getAnnotatedBounds();
 }
--- a/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java	Tue Oct 08 14:57:32 2013 -0700
@@ -26,24 +26,25 @@
 package java.lang.reflect;
 
 /**
- * AnnotatedWildcardType represents the use of a wildcard type argument, whose
- * upper or lower bounds may themselves represent annotated uses of types.
+ * {@code AnnotatedWildcardType} represents the potentially annotated use of a
+ * wildcard type argument, whose upper or lower bounds may themselves represent
+ * annotated uses of types.
  *
  * @since 1.8
  */
 public interface AnnotatedWildcardType extends AnnotatedType {
 
     /**
-     * Returns the annotated lower bounds of this wildcard type.
+     * Returns the potentially annotated lower bounds of this wildcard type.
      *
-     * @return the annotated lower bounds of this wildcard type
+     * @return the potentially annotated lower bounds of this wildcard type
      */
     AnnotatedType[] getAnnotatedLowerBounds();
 
     /**
-     * Returns the annotated upper bounds of this wildcard type.
+     * Returns the potentially annotated upper bounds of this wildcard type.
      *
-     * @return the annotated upper bounds of this wildcard type
+     * @return the potentially annotated upper bounds of this wildcard type
      */
     AnnotatedType[] getAnnotatedUpperBounds();
 }
--- a/src/share/classes/java/lang/reflect/Constructor.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/Constructor.java	Tue Oct 08 14:57:32 2013 -0700
@@ -67,8 +67,6 @@
     private transient ConstructorRepository genericInfo;
     private byte[]              annotations;
     private byte[]              parameterAnnotations;
-    // This is set by the vm at Constructor creation
-    private byte[]              typeAnnotations;
 
     // Generics infrastructure
     // Accessor for factory
@@ -141,8 +139,6 @@
         res.root = this;
         // Might as well eagerly propagate this if already present
         res.constructorAccessor = constructorAccessor;
-
-        res.typeAnnotations = typeAnnotations;
         return res;
     }
 
@@ -155,10 +151,6 @@
     byte[] getAnnotationBytes() {
         return annotations;
     }
-    @Override
-    byte[] getTypeAnnotationBytes() {
-        return typeAnnotations;
-    }
 
     /**
      * {@inheritDoc}
--- a/src/share/classes/java/lang/reflect/Executable.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/Executable.java	Tue Oct 08 14:57:32 2013 -0700
@@ -51,7 +51,6 @@
      * Accessor method to allow code sharing
      */
     abstract byte[] getAnnotationBytes();
-    abstract byte[] getTypeAnnotationBytes();
 
     /**
      * Does the Executable have generic information.
@@ -287,12 +286,14 @@
      * this object.  Returns an array of length 0 if the executable
      * has no parameters.
      *
-     * The parameters of the underlying executable do not necessarily
+     * <p>The parameters of the underlying executable do not necessarily
      * have unique names, or names that are legal identifiers in the
      * Java programming language (JLS 3.8).
      *
+     * @throws MalformedParametersException if the class file contains
+     * a MethodParameters attribute that is improperly formatted.
      * @return an array of {@code Parameter} objects representing all
-     * the parameters to the executable this object represents
+     * the parameters to the executable this object represents.
      */
     public Parameter[] getParameters() {
         // TODO: This may eventually need to be guarded by security
@@ -316,6 +317,30 @@
         return out;
     }
 
+    private void verifyParameters(final Parameter[] parameters) {
+        final int mask = Modifier.FINAL | Modifier.SYNTHETIC | Modifier.MANDATED;
+
+        if (getParameterTypes().length != parameters.length)
+            throw new MalformedParametersException("Wrong number of parameters in MethodParameters attribute");
+
+        for (Parameter parameter : parameters) {
+            final String name = parameter.getRealName();
+            final int mods = parameter.getModifiers();
+
+            if (name != null) {
+                if (name.isEmpty() || name.indexOf('.') != -1 ||
+                    name.indexOf(';') != -1 || name.indexOf('[') != -1 ||
+                    name.indexOf('/') != -1) {
+                    throw new MalformedParametersException("Invalid parameter name \"" + name + "\"");
+                }
+            }
+
+            if (mods != (mods & mask)) {
+                throw new MalformedParametersException("Invalid parameter modifiers");
+            }
+        }
+    }
+
     private Parameter[] privateGetParameters() {
         // Use tmp to avoid multiple writes to a volatile.
         Parameter[] tmp = parameters;
@@ -323,7 +348,12 @@
         if (tmp == null) {
 
             // Otherwise, go to the JVM to get them
-            tmp = getParameters0();
+            try {
+                tmp = getParameters0();
+            } catch(IllegalArgumentException e) {
+                // Rethrow ClassFormatErrors
+                throw new MalformedParametersException("Invalid constant pool index");
+            }
 
             // If we get back nothing, then synthesize parameters
             if (tmp == null) {
@@ -331,6 +361,7 @@
                 tmp = synthesizeAllParams();
             } else {
                 hasRealParameterData = true;
+                verifyParameters(tmp);
             }
 
             parameters = tmp;
@@ -352,6 +383,12 @@
     private transient volatile Parameter[] parameters;
 
     private native Parameter[] getParameters0();
+    private native byte[] getTypeAnnotationBytes0();
+
+    // Needed by reflectaccess
+    byte[] getTypeAnnotationBytes() {
+        return getTypeAnnotationBytes0();
+    }
 
     /**
      * Returns an array of {@code Class} objects that represent the
@@ -514,18 +551,20 @@
     }
 
     /**
-     * Returns an AnnotatedType object that represents the use of a type to
+     * Returns an {@code 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
-     * represents the type of the constructed object.
+     * If this {@code Executable} object represents a constructor, the {@code
+     * AnnotatedType} object represents the type of the constructed object.
      *
-     * If this Executable represents a method, the AnnotatedType object
-     * represents the use of a type to specify the return type of the method.
+     * If this {@code Executable} object represents a method, the {@code
+     * AnnotatedType} object represents the use of a type to specify the return
+     * type of the method.
      *
-     * @return an object representing the return type of this method
-     * or constructor
+     * @return an object representing the return type of the method
+     * or constructor represented by this {@code Executable}
+     *
      * @since 1.8
      */
     public abstract AnnotatedType getAnnotatedReturnType();
@@ -539,7 +578,7 @@
      * @since 1.8
      */
     AnnotatedType getAnnotatedReturnType0(Type returnType) {
-        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
+        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
                 sun.misc.SharedSecrets.getJavaLangAccess().
                         getConstantPool(getDeclaringClass()),
                 this,
@@ -549,25 +588,30 @@
     }
 
     /**
-     * Returns an AnnotatedType object that represents the use of a type to
-     * specify the receiver type of the method/constructor represented by this
-     * Executable. The receiver type of a method/constructor is available only
-     * if the method/constructor declares a formal parameter called 'this'.
+     * Returns an {@code AnnotatedType} object that represents the use of a
+     * type to specify the receiver type of the method/constructor represented
+     * by this Executable object. The receiver type of a method/constructor is
+     * available only if the method/constructor has a <em>receiver
+     * parameter</em> (JLS 8.4.1).
      *
-     * Returns null if this Executable represents a constructor or instance
-     * method that either declares no formal parameter called 'this', or
-     * declares a formal parameter called 'this' with no annotations on its
-     * type.
+     * If this {@code Executable} object represents a constructor or instance
+     * method that does not have a receiver parameter, or has a receiver
+     * parameter with no annotations on its type, then the return value is an
+     * {@code AnnotatedType} object representing an element with no
+     * annotations.
      *
-     * Returns null if this Executable represents a static method.
+     * If this {@code Executable} object represents a static method, then the
+     * return value is null.
      *
-     * @return an object representing the receiver type of the
-     * method or constructor represented by this Executable
+     * @return an object representing the receiver type of the method or
+     * constructor represented by this {@code Executable}
      *
      * @since 1.8
      */
     public AnnotatedType getAnnotatedReceiverType() {
-        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
+        if (Modifier.isStatic(this.getModifiers()))
+            return null;
+        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
                 sun.misc.SharedSecrets.getJavaLangAccess().
                         getConstantPool(getDeclaringClass()),
                 this,
@@ -577,8 +621,8 @@
     }
 
     /**
-     * Returns an array of AnnotatedType objects that represent the use of
-     * types to specify formal parameter types of the method/constructor
+     * Returns an array of {@code AnnotatedType} objects that represent the use
+     * of types to specify formal parameter types of the method/constructor
      * represented by this Executable. The order of the objects in the array
      * corresponds to the order of the formal parameter types in the
      * declaration of the method/constructor.
@@ -587,12 +631,13 @@
      * parameters.
      *
      * @return an array of objects representing the types of the
-     * formal parameters of this method or constructor
+     * formal parameters of the method or constructor represented by this
+     * {@code Executable}
      *
      * @since 1.8
      */
     public AnnotatedType[] getAnnotatedParameterTypes() {
-        return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(),
+        return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
                 sun.misc.SharedSecrets.getJavaLangAccess().
                         getConstantPool(getDeclaringClass()),
                 this,
@@ -602,8 +647,8 @@
     }
 
     /**
-     * Returns an array of AnnotatedType objects that represent the use of
-     * types to specify the declared exceptions of the method/constructor
+     * Returns an array of {@code AnnotatedType} objects that represent the use
+     * of types to specify the declared exceptions of the method/constructor
      * represented by this Executable. The order of the objects in the array
      * corresponds to the order of the exception types in the declaration of
      * the method/constructor.
@@ -612,12 +657,13 @@
      * exceptions.
      *
      * @return an array of objects representing the declared
-     * exceptions of this method or constructor
+     * exceptions of the method or constructor represented by this {@code
+     * Executable}
      *
      * @since 1.8
      */
     public AnnotatedType[] getAnnotatedExceptionTypes() {
-        return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(),
+        return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes0(),
                 sun.misc.SharedSecrets.getJavaLangAccess().
                         getConstantPool(getDeclaringClass()),
                 this,
--- a/src/share/classes/java/lang/reflect/Field.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/Field.java	Tue Oct 08 14:57:32 2013 -0700
@@ -82,8 +82,6 @@
     // currently only two levels deep (i.e., one root Field and
     // potentially many Field objects pointing to it.)
     private Field               root;
-    // This is set by the vm at Field creation
-    private byte[]              typeAnnotations;
 
     // Generics infrastructure
 
@@ -149,7 +147,6 @@
         res.fieldAccessor = fieldAccessor;
         res.overrideFieldAccessor = overrideFieldAccessor;
 
-        res.typeAnnotations = typeAnnotations;
         return res;
     }
 
@@ -1148,6 +1145,8 @@
         return declaredAnnotations;
     }
 
+    private native byte[] getTypeAnnotationBytes0();
+
     /**
      * Returns an AnnotatedType object that represents the use of a type to specify
      * the declared type of the field represented by this Field.
@@ -1157,7 +1156,7 @@
      * @since 1.8
      */
     public AnnotatedType getAnnotatedType() {
-        return TypeAnnotationParser.buildAnnotatedType(typeAnnotations,
+        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes0(),
                                                        sun.misc.SharedSecrets.getJavaLangAccess().
                                                            getConstantPool(getDeclaringClass()),
                                                        this,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/reflect/MalformedParametersException.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+/**
+ * Thrown when {@link java.lang.reflect.Executable#getParameters the
+ * java.lang.reflect package} attempts to read method parameters from
+ * a class file and determines that one or more parameters are
+ * malformed.
+ *
+ * <p>The following is a list of conditions under which this exception
+ * can be thrown:
+ * <ul>
+ * <li> The number of parameters (parameter_count) is wrong for the method
+ * <li> A constant pool index is out of bounds.
+ * <li> A constant pool index does not refer to a UTF-8 entry
+ * <li> A parameter's name is "", or contains an illegal character
+ * <li> The flags field contains an illegal flag (something other than
+ *     FINAL, SYNTHETIC, or MANDATED)
+ * </ul>
+ *
+ * See {@link java.lang.reflect.Executable#getParameters} for more
+ * information.
+ *
+ * @see java.lang.reflect.Executable#getParameters
+ * @since 1.8
+ */
+public class MalformedParametersException extends RuntimeException {
+
+    private static final long serialVersionUID = 20130919L;
+
+    public MalformedParametersException() {}
+
+    public MalformedParametersException(String reason) {
+        super(reason);
+    }
+}
--- a/src/share/classes/java/lang/reflect/Method.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/Method.java	Tue Oct 08 14:57:32 2013 -0700
@@ -80,8 +80,6 @@
     // currently only two levels deep (i.e., one root Method and
     // potentially many Method objects pointing to it.)
     private Method              root;
-    // This is set by the vm at Method creation
-    private byte[]              typeAnnotations;
 
     // Generics infrastructure
     private String getGenericSignature() {return signature;}
@@ -152,8 +150,6 @@
         res.root = this;
         // Might as well eagerly propagate this if already present
         res.methodAccessor = methodAccessor;
-
-        res.typeAnnotations = typeAnnotations;
         return res;
     }
 
@@ -166,10 +162,6 @@
     byte[] getAnnotationBytes() {
         return annotations;
     }
-    @Override
-    byte[] getTypeAnnotationBytes() {
-        return typeAnnotations;
-    }
 
     /**
      * {@inheritDoc}
--- a/src/share/classes/java/lang/reflect/Parameter.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/lang/reflect/Parameter.java	Tue Oct 08 14:57:32 2013 -0700
@@ -104,7 +104,7 @@
      * to the class file.
      */
     public boolean isNamePresent() {
-        return executable.hasRealParameterData();
+        return executable.hasRealParameterData() && name != null;
     }
 
     /**
@@ -182,6 +182,11 @@
             return name;
     }
 
+    // Package-private accessor to the real name field.
+    String getRealName() {
+        return name;
+    }
+
     /**
      * Returns a {@code Type} object that identifies the parameterized
      * type for the parameter represented by this {@code Parameter}
--- a/src/share/classes/java/nio/file/Files.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/nio/file/Files.java	Tue Oct 08 14:57:32 2013 -0700
@@ -2128,7 +2128,7 @@
     /**
      * Tests whether a file is a symbolic link.
      *
-     * <p> Where is it required to distinguish an I/O exception from the case
+     * <p> Where it is required to distinguish an I/O exception from the case
      * that the file is not a symbolic link then the file attributes can be
      * read with the {@link #readAttributes(Path,Class,LinkOption[])
      * readAttributes} method and the file type tested with the {@link
@@ -2164,7 +2164,7 @@
      * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
      * NOFOLLOW_LINKS} is present then symbolic links are not followed.
      *
-     * <p> Where is it required to distinguish an I/O exception from the case
+     * <p> Where it is required to distinguish an I/O exception from the case
      * that the file is not a directory then the file attributes can be
      * read with the {@link #readAttributes(Path,Class,LinkOption[])
      * readAttributes} method and the file type tested with the {@link
@@ -2201,7 +2201,7 @@
      * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
      * NOFOLLOW_LINKS} is present then symbolic links are not followed.
      *
-     * <p> Where is it required to distinguish an I/O exception from the case
+     * <p> Where it is required to distinguish an I/O exception from the case
      * that the file is not a regular file then the file attributes can be
      * read with the {@link #readAttributes(Path,Class,LinkOption[])
      * readAttributes} method and the file type tested with the {@link
@@ -3082,13 +3082,13 @@
      *          method is invoked to check read access to the file.
      */
     public static byte[] readAllBytes(Path path) throws IOException {
-        try (FileChannel fc = FileChannel.open(path);
-             InputStream is = Channels.newInputStream(fc)) {
-            long size = fc.size();
+        try (SeekableByteChannel sbc = Files.newByteChannel(path);
+             InputStream in = Channels.newInputStream(sbc)) {
+            long size = sbc.size();
             if (size > (long)MAX_BUFFER_SIZE)
                 throw new OutOfMemoryError("Required array size too large");
 
-            return read(is, (int)size);
+            return read(in, (int)size);
         }
     }
 
--- a/src/share/classes/java/nio/file/Path.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/nio/file/Path.java	Tue Oct 08 14:57:32 2013 -0700
@@ -315,7 +315,7 @@
      * and parent directory. In such file systems all occurrences of "{@code .}"
      * are considered redundant. If a "{@code ..}" is preceded by a
      * non-"{@code ..}" name then both names are considered redundant (the
-     * process to identify such names is repeated until is it no longer
+     * process to identify such names is repeated until it is no longer
      * applicable).
      *
      * <p> This method does not access the file system; the path may not locate
--- a/src/share/classes/java/security/SecureRandom.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/security/SecureRandom.java	Tue Oct 08 14:57:32 2013 -0700
@@ -578,39 +578,30 @@
     /**
      * Returns a {@code SecureRandom} object that was selected by using
      * the algorithms/providers specified in the {@code
-     * securerandom.strongAlgorithms} Security property.
+     * securerandom.strongAlgorithms} {@link Security} property.
      * <p>
      * Some situations require strong random values, such as when
      * creating high-value/long-lived secrets like RSA public/private
      * keys.  To help guide applications in selecting a suitable strong
-     * {@code SecureRandom} implementation, Java distributions should
+     * {@code SecureRandom} implementation, Java distributions
      * include a list of known strong {@code SecureRandom}
      * implementations in the {@code securerandom.strongAlgorithms}
      * Security property.
-     *
-     * <pre>
-     *     SecureRandom sr = SecureRandom.getStrongSecureRandom();
-     *
-     *     if (sr == null) {
-     *         // Decide if this is a problem, and whether to recover.
-     *         sr = new SecureRandom();
-     *         if (!goodEnough(sr)) {
-     *             return;
-     *         }
-     *     }
-     *
-     *     keyPairGenerator.initialize(2048, sr);
-     * </pre>
+     * <p>
+     * Every implementation of the Java platform is required to
+     * support at least one strong {@code SecureRandom} implementation.
      *
      * @return a strong {@code SecureRandom} implementation as indicated
-     * by the {@code securerandom.strongAlgorithms} Security property, or
-     * null if none are available.
+     * by the {@code securerandom.strongAlgorithms} Security property
+     *
+     * @throws NoSuchAlgorithmException if no algorithm is available
      *
      * @see Security#getProperty(String)
      *
      * @since 1.8
      */
-    public static SecureRandom getStrongSecureRandom() {
+    public static SecureRandom getInstanceStrong()
+            throws NoSuchAlgorithmException {
 
         String property = AccessController.doPrivileged(
             new PrivilegedAction<String>() {
@@ -622,7 +613,8 @@
             });
 
         if ((property == null) || (property.length() == 0)) {
-            return null;
+            throw new NoSuchAlgorithmException(
+                "Null/empty securerandom.strongAlgorithms Security Property");
         }
 
         String remainder = property;
@@ -649,7 +641,8 @@
             }
         }
 
-        return null;
+        throw new NoSuchAlgorithmException(
+            "No strong SecureRandom impls available: " + property);
     }
 
     // Declare serialVersionUID to be compatible with JDK1.1
--- a/src/share/classes/java/time/Duration.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/Duration.java	Tue Oct 08 14:57:32 2013 -0700
@@ -441,9 +441,13 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Obtains a {@code Duration} representing the duration between two instants.
+     * Obtains a {@code Duration} representing the duration between two temporal objects.
      * <p>
-     * This calculates the duration between two temporal objects of the same type.
+     * This calculates the duration between two temporal objects. If the objects
+     * are of different types, then the duration is calculated based on the type
+     * of the first object. For example, if the first argument is a {@code LocalTime}
+     * then the second argument is converted to a {@code LocalTime}.
+     * <p>
      * The specified temporal objects must support the {@link ChronoUnit#SECONDS SECONDS} unit.
      * For full accuracy, either the {@link ChronoUnit#NANOS NANOS} unit or the
      * {@link ChronoField#NANO_OF_SECOND NANO_OF_SECOND} field should be supported.
--- a/src/share/classes/java/time/Instant.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/Instant.java	Tue Oct 08 14:57:32 2013 -0700
@@ -362,6 +362,10 @@
      * @throws DateTimeException if unable to convert to an {@code Instant}
      */
     public static Instant from(TemporalAccessor temporal) {
+        if (temporal instanceof Instant) {
+            return (Instant) temporal;
+        }
+        Objects.requireNonNull(temporal, "temporal");
         long instantSecs = temporal.getLong(INSTANT_SECONDS);
         int nanoOfSecond = temporal.get(NANO_OF_SECOND);
         return Instant.ofEpochSecond(instantSecs, nanoOfSecond);
@@ -370,7 +374,7 @@
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code Instant} from a text string such as
-     * {@code 2007-12-03T10:15:30:00}.
+     * {@code 2007-12-03T10:15:30.00Z}.
      * <p>
      * The string must represent a valid instant in UTC and is parsed using
      * {@link DateTimeFormatter#ISO_INSTANT}.
@@ -1091,7 +1095,8 @@
      * 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}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code Instant} using {@link #from(TemporalAccessor)}.
      * For example, the amount in days between two dates can be calculated
      * using {@code startInstant.until(endInstant, SECONDS)}.
      * <p>
@@ -1112,25 +1117,22 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endInstant  the end date, which must be an {@code Instant}, not null
+     * @param endExclusive  the end date, exclusive, which is converted to 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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to an {@code Instant}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endInstant, TemporalUnit unit) {
-        if (endInstant instanceof Instant == false) {
-            Objects.requireNonNull(endInstant, "endInstant");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
-        Instant end = (Instant) endInstant;
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        Instant end = Instant.from(endExclusive);
         if (unit instanceof ChronoUnit) {
             ChronoUnit f = (ChronoUnit) unit;
             switch (f) {
@@ -1145,7 +1147,7 @@
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
-        return unit.between(this, endInstant);
+        return unit.between(this, end);
     }
 
     private long nanosUntil(Instant end) {
--- a/src/share/classes/java/time/LocalDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/LocalDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -353,6 +353,7 @@
      * @throws DateTimeException if unable to convert to a {@code LocalDate}
      */
     public static LocalDate from(TemporalAccessor temporal) {
+        Objects.requireNonNull(temporal, "temporal");
         LocalDate date = temporal.query(TemporalQuery.localDate());
         if (date == null) {
             throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + temporal.getClass());
@@ -1125,6 +1126,11 @@
      */
     @Override
     public LocalDate plus(TemporalAmount amountToAdd) {
+        if (amountToAdd instanceof Period) {
+            Period periodToAdd = (Period) amountToAdd;
+            return plusMonths(periodToAdd.toTotalMonths()).plusDays(periodToAdd.getDays());
+        }
+        Objects.requireNonNull(amountToAdd, "amountToAdd");
         return (LocalDate) amountToAdd.addTo(this);
     }
 
@@ -1353,6 +1359,11 @@
      */
     @Override
     public LocalDate minus(TemporalAmount amountToSubtract) {
+        if (amountToSubtract instanceof Period) {
+            Period periodToSubtract = (Period) amountToSubtract;
+            return minusMonths(periodToSubtract.toTotalMonths()).minusDays(periodToSubtract.getDays());
+        }
+        Objects.requireNonNull(amountToSubtract, "amountToSubtract");
         return (LocalDate) amountToSubtract.subtractFrom(this);
     }
 
@@ -1531,7 +1542,8 @@
      * 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}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code LocalDate} using {@link #from(TemporalAccessor)}.
      * For example, the amount in days between two dates can be calculated
      * using {@code startDate.until(endDate, DAYS)}.
      * <p>
@@ -1557,26 +1569,22 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endDate  the end date, which must be a {@code LocalDate}, not null
+     * @param endExclusive  the end date, exclusive, which is converted to a {@code LocalDate}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to a {@code LocalDate}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endDate, TemporalUnit unit) {
-        Objects.requireNonNull(unit, "unit");
-        if (endDate instanceof LocalDate == false) {
-            Objects.requireNonNull(endDate, "endDate");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
-        LocalDate end = (LocalDate) endDate;
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        LocalDate end = LocalDate.from(endExclusive);
         if (unit instanceof ChronoUnit) {
             switch ((ChronoUnit) unit) {
                 case DAYS: return daysUntil(end);
@@ -1590,7 +1598,7 @@
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
-        return unit.between(this, endDate);
+        return unit.between(this, end);
     }
 
     long daysUntil(LocalDate end) {
@@ -1632,12 +1640,12 @@
      * </pre>
      * The choice should be made based on which makes the code more readable.
      *
-     * @param endDate  the end date, exclusive, which may be in any chronology, not null
+     * @param endDateExclusive  the end date, exclusive, which may be in any chronology, not null
      * @return the period between this date and the end date, not null
      */
     @Override
-    public Period until(ChronoLocalDate endDate) {
-        LocalDate end = LocalDate.from(endDate);
+    public Period until(ChronoLocalDate endDateExclusive) {
+        LocalDate end = LocalDate.from(endDateExclusive);
         long totalMonths = end.getProlepticMonth() - this.getProlepticMonth();  // safe
         int days = end.day - this.day;
         if (totalMonths > 0 && days < 0) {
--- a/src/share/classes/java/time/LocalDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/LocalDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1129,6 +1129,11 @@
      */
     @Override
     public LocalDateTime plus(TemporalAmount amountToAdd) {
+        if (amountToAdd instanceof Period) {
+            Period periodToAdd = (Period) amountToAdd;
+            return with(date.plus(periodToAdd), time);
+        }
+        Objects.requireNonNull(amountToAdd, "amountToAdd");
         return (LocalDateTime) amountToAdd.addTo(this);
     }
 
@@ -1343,6 +1348,11 @@
      */
     @Override
     public LocalDateTime minus(TemporalAmount amountToSubtract) {
+        if (amountToSubtract instanceof Period) {
+            Period periodToSubtract = (Period) amountToSubtract;
+            return with(date.minus(periodToSubtract), time);
+        }
+        Objects.requireNonNull(amountToSubtract, "amountToSubtract");
         return (LocalDateTime) amountToSubtract.subtractFrom(this);
     }
 
@@ -1611,7 +1621,8 @@
      * 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}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code LocalDateTime} using {@link #from(TemporalAccessor)}.
      * For example, the amount in days between two date-times can be calculated
      * using {@code startDateTime.until(endDateTime, DAYS)}.
      * <p>
@@ -1639,25 +1650,22 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * 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 endExclusive  the end date, exclusive, which is converted to a {@code LocalDateTime}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to a {@code LocalDateTime}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endDateTime, TemporalUnit unit) {
-        if (endDateTime instanceof LocalDateTime == false) {
-            Objects.requireNonNull(endDateTime, "endDateTime");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
-        LocalDateTime end = (LocalDateTime) endDateTime;
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        LocalDateTime end = LocalDateTime.from(endExclusive);
         if (unit instanceof ChronoUnit) {
             if (unit.isTimeBased()) {
                 long amount = date.daysUntil(end.date);
@@ -1711,7 +1719,7 @@
             }
             return date.until(endDate, unit);
         }
-        return unit.between(this, endDateTime);
+        return unit.between(this, end);
     }
 
     /**
--- a/src/share/classes/java/time/LocalTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/LocalTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -394,6 +394,7 @@
      * @throws DateTimeException if unable to convert to a {@code LocalTime}
      */
     public static LocalTime from(TemporalAccessor temporal) {
+        Objects.requireNonNull(temporal, "temporal");
         LocalTime time = temporal.query(TemporalQuery.localTime());
         if (time == null) {
             throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass());
@@ -1330,7 +1331,8 @@
      * 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}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code LocalTime} using {@link #from(TemporalAccessor)}.
      * For example, the amount in hours between two times can be calculated
      * using {@code startTime.until(endTime, HOURS)}.
      * <p>
@@ -1356,25 +1358,22 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endTime  the end time, which must be a {@code LocalTime}, not null
+     * @param endExclusive  the end time, exclusive, which is converted to a {@code LocalTime}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to a {@code LocalTime}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endTime, TemporalUnit unit) {
-        if (endTime instanceof LocalTime == false) {
-            Objects.requireNonNull(endTime, "endTime");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
-        LocalTime end = (LocalTime) endTime;
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        LocalTime end = LocalTime.from(endExclusive);
         if (unit instanceof ChronoUnit) {
             long nanosUntil = end.toNanoOfDay() - toNanoOfDay();  // no overflow
             switch ((ChronoUnit) unit) {
@@ -1388,7 +1387,7 @@
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
-        return unit.between(this, endTime);
+        return unit.between(this, end);
     }
 
     /**
--- a/src/share/classes/java/time/MonthDay.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/MonthDay.java	Tue Oct 08 14:57:32 2013 -0700
@@ -246,7 +246,8 @@
      * <p>
      * The conversion extracts the {@link ChronoField#MONTH_OF_YEAR MONTH_OF_YEAR} and
      * {@link ChronoField#DAY_OF_MONTH DAY_OF_MONTH} fields.
-     * The extraction is only permitted if the date-time has an ISO chronology.
+     * The extraction is only permitted if the temporal object has an ISO
+     * chronology, or can be converted to a {@code LocalDate}.
      * <p>
      * This method matches the signature of the functional interface {@link TemporalQuery}
      * allowing it to be used in queries via method reference, {@code MonthDay::from}.
--- a/src/share/classes/java/time/OffsetDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/OffsetDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1592,7 +1592,8 @@
      * For example, the period in days between two date-times can be calculated
      * using {@code startDateTime.until(endDateTime, DAYS)}.
      * <p>
-     * The {@code Temporal} passed to this method must be an {@code OffsetDateTime}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code OffsetDateTime} using {@link #from(TemporalAccessor)}.
      * If the offset differs between the two date-times, the specified
      * end date-time is normalized to have the same offset as this date-time.
      * <p>
@@ -1620,30 +1621,27 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * 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 endExclusive  the end date, exclusive, which is converted to an {@code OffsetDateTime}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to an {@code OffsetDateTime}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endDateTime, TemporalUnit unit) {
-        if (endDateTime instanceof OffsetDateTime == false) {
-            Objects.requireNonNull(endDateTime, "endDateTime");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        OffsetDateTime end = OffsetDateTime.from(endExclusive);
         if (unit instanceof ChronoUnit) {
-            OffsetDateTime end = (OffsetDateTime) endDateTime;
             end = end.withOffsetSameInstant(offset);
             return dateTime.until(end.dateTime, unit);
         }
-        return unit.between(this, endDateTime);
+        return unit.between(this, end);
     }
 
     /**
--- a/src/share/classes/java/time/OffsetTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/OffsetTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1124,7 +1124,8 @@
      * For example, the period in hours between two times can be calculated
      * using {@code startTime.until(endTime, HOURS)}.
      * <p>
-     * The {@code Temporal} passed to this method must be an {@code OffsetTime}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code OffsetTime} using {@link #from(TemporalAccessor)}.
      * If the offset differs between the two times, then the specified
      * end time is normalized to have the same offset as this time.
      * <p>
@@ -1150,26 +1151,23 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endTime  the end time, which must be an {@code OffsetTime}, not null
+     * @param endExclusive  the end date, exclusive, which is converted to an {@code OffsetTime}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to an {@code OffsetTime}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endTime, TemporalUnit unit) {
-        if (endTime instanceof OffsetTime == false) {
-            Objects.requireNonNull(endTime, "endTime");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        OffsetTime end = OffsetTime.from(endExclusive);
         if (unit instanceof ChronoUnit) {
-            OffsetTime end = (OffsetTime) endTime;
             long nanosUntil = end.toEpochNano() - toEpochNano();  // no overflow
             switch ((ChronoUnit) unit) {
                 case NANOS: return nanosUntil;
@@ -1182,7 +1180,7 @@
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
-        return unit.between(this, endTime);
+        return unit.between(this, end);
     }
 
     /**
--- a/src/share/classes/java/time/Period.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/Period.java	Tue Oct 08 14:57:32 2013 -0700
@@ -61,7 +61,6 @@
  */
 package java.time;
 
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoUnit.DAYS;
 import static java.time.temporal.ChronoUnit.MONTHS;
 import static java.time.temporal.ChronoUnit.YEARS;
@@ -70,17 +69,19 @@
 import java.io.DataOutput;
 import java.io.IOException;
 import java.io.InvalidObjectException;
-import java.io.InvalidObjectException;
 import java.io.Serializable;
 import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoPeriod;
 import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalQuery;
 import java.time.temporal.TemporalUnit;
 import java.time.temporal.UnsupportedTemporalTypeException;
-import java.time.temporal.ValueRange;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -89,12 +90,13 @@
 import java.util.regex.Pattern;
 
 /**
- * A date-based amount of time, such as '2 years, 3 months and 4 days'.
+ * A date-based amount of time in the ISO-8601 calendar system,
+ * such as '2 years, 3 months and 4 days'.
  * <p>
  * This class models a quantity or amount of time in terms of years, months and days.
  * See {@link Duration} for the time-based equivalent to this class.
  * <p>
- * Durations and period differ in their treatment of daylight savings time
+ * Durations and periods differ in their treatment of daylight savings time
  * when added to {@link ZonedDateTime}. A {@code Duration} will add an exact
  * number of seconds, thus a duration of one day is always exactly 24 hours.
  * By contrast, a {@code Period} will add a conceptual day, trying to maintain
@@ -110,14 +112,12 @@
  * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
  * All three fields are always present, but may be set to zero.
  * <p>
- * The period may be used with any calendar system.
- * The meaning of a "year" or "month" is only applied when the object is added to a date.
+ * The ISO-8601 calendar system is the modern civil calendar system used today
+ * in most of the world. It is equivalent to the proleptic Gregorian calendar
+ * system, in which today's rules for leap years are applied for all time.
  * <p>
  * The period is modeled as a directed amount of time, meaning that individual parts of the
  * period may be negative.
- * <p>
- * 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.
  *
  * @implSpec
  * This class is immutable and thread-safe.
@@ -125,7 +125,7 @@
  * @since 1.8
  */
 public final class Period
-        implements TemporalAmount, Serializable {
+        implements ChronoPeriod, Serializable {
 
     /**
      * A constant for a period of zero.
@@ -140,6 +140,7 @@
      */
     private final static Pattern PATTERN =
             Pattern.compile("([-+]?)P(?:([-+]?[0-9]+)Y)?(?:([-+]?[0-9]+)M)?(?:([-+]?[0-9]+)W)?(?:([-+]?[0-9]+)D)?", Pattern.CASE_INSENSITIVE);
+
     /**
      * The set of supported units.
      */
@@ -234,12 +235,14 @@
      * <p>
      * This obtains a period based on the specified amount.
      * A {@code TemporalAmount} represents an  amount of time, which may be
-     * date-based or time-based, which this factory extracts to a period.
+     * date-based or time-based, which this factory extracts to a {@code Period}.
      * <p>
      * The conversion loops around the set of units from the amount and uses
      * the {@link ChronoUnit#YEARS YEARS}, {@link ChronoUnit#MONTHS MONTHS}
      * and {@link ChronoUnit#DAYS DAYS} units to create a period.
      * If any other units are found then an exception is thrown.
+     * <p>
+     * If the amount is a {@code ChronoPeriod} then it must use the ISO chronology.
      *
      * @param amount  the temporal amount to convert, not null
      * @return the equivalent period, not null
@@ -247,6 +250,14 @@
      * @throws ArithmeticException if the amount of years, months or days exceeds an int
      */
     public static Period from(TemporalAmount amount) {
+        if (amount instanceof Period) {
+            return (Period) amount;
+        }
+        if (amount instanceof ChronoPeriod) {
+            if (IsoChronology.INSTANCE.equals(((ChronoPeriod) amount).getChronology()) == false) {
+                throw new DateTimeException("Period requires ISO chronology: " + amount);
+            }
+        }
         Objects.requireNonNull(amount, "amount");
         int years = 0;
         int months = 0;
@@ -358,13 +369,13 @@
      * The result of this method can be a negative period if the end is before the start.
      * The negative sign will be the same in each of year, month and day.
      *
-     * @param startDate  the start date, inclusive, not null
-     * @param endDate  the end date, exclusive, not null
+     * @param startDateInclusive  the start date, inclusive, not null
+     * @param endDateExclusive  the end date, exclusive, not null
      * @return the period between this date and the end date, not null
      * @see ChronoLocalDate#until(ChronoLocalDate)
      */
-    public static Period between(LocalDate startDate, LocalDate endDate) {
-        return startDate.until(endDate);
+    public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive) {
+        return startDateInclusive.until(endDateExclusive);
     }
 
     //-----------------------------------------------------------------------
@@ -439,6 +450,21 @@
         return SUPPORTED_UNITS;
     }
 
+    /**
+     * Gets the chronology of this period, which is the ISO calendar system.
+     * <p>
+     * The {@code Chronology} represents the calendar system in use.
+     * The ISO-8601 calendar system is the modern civil calendar system used today
+     * in most of the world. It is equivalent to the proleptic Gregorian calendar
+     * system, in which today's rules for leap years are applied for all time.
+     *
+     * @return the ISO chronology, not null
+     */
+    @Override
+    public IsoChronology getChronology() {
+        return IsoChronology.INSTANCE;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Checks if all three units of this period are zero.
@@ -468,7 +494,7 @@
      * <p>
      * This returns the years unit.
      * <p>
-     * The months unit is not normalized with the years unit.
+     * The months unit is not automatically normalized with the years unit.
      * This means that a period of "15 months" is different to a period
      * of "1 year and 3 months".
      *
@@ -483,7 +509,7 @@
      * <p>
      * This returns the months unit.
      * <p>
-     * The months unit is not normalized with the years unit.
+     * The months unit is not automatically normalized with the years unit.
      * This means that a period of "15 months" is different to a period
      * of "1 year and 3 months".
      *
@@ -511,7 +537,7 @@
      * This sets the amount of the years unit in a copy of this period.
      * The months and days units are unaffected.
      * <p>
-     * The months unit is not normalized with the years unit.
+     * The months unit is not automatically normalized with the years unit.
      * This means that a period of "15 months" is different to a period
      * of "1 year and 3 months".
      * <p>
@@ -533,7 +559,7 @@
      * This sets the amount of the months unit in a copy of this period.
      * The years and days units are unaffected.
      * <p>
-     * The months unit is not normalized with the years unit.
+     * The months unit is not automatically normalized with the years unit.
      * This means that a period of "15 months" is different to a period
      * of "1 year and 3 months".
      * <p>
@@ -572,21 +598,28 @@
      * Returns a copy of this period with the specified period added.
      * <p>
      * This operates separately on the years, months and days.
+     * No normalization is performed.
      * <p>
      * For example, "1 year, 6 months and 3 days" plus "2 years, 2 months and 2 days"
      * returns "3 years, 8 months and 5 days".
      * <p>
+     * The specified amount is typically an instance of {@code Period}.
+     * Other types are interpreted using {@link Period#from(TemporalAmount)}.
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToAdd  the period to add, not null
      * @return a {@code Period} based on this period with the requested period added, not null
+     * @throws DateTimeException if the specified amount has a non-ISO chronology or
+     *  contains an invalid unit
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public Period plus(Period amountToAdd) {
+    public Period plus(TemporalAmount amountToAdd) {
+        Period isoAmount = Period.from(amountToAdd);
         return create(
-                Math.addExact(years, amountToAdd.years),
-                Math.addExact(months, amountToAdd.months),
-                Math.addExact(days, amountToAdd.days));
+                Math.addExact(years, isoAmount.years),
+                Math.addExact(months, isoAmount.months),
+                Math.addExact(days, isoAmount.days));
     }
 
     /**
@@ -654,21 +687,28 @@
      * Returns a copy of this period with the specified period subtracted.
      * <p>
      * This operates separately on the years, months and days.
+     * No normalization is performed.
      * <p>
      * For example, "1 year, 6 months and 3 days" minus "2 years, 2 months and 2 days"
      * returns "-1 years, 4 months and 1 day".
      * <p>
+     * The specified amount is typically an instance of {@code Period}.
+     * Other types are interpreted using {@link Period#from(TemporalAmount)}.
+     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @param amountToSubtract  the period to subtract, not null
      * @return a {@code Period} based on this period with the requested period subtracted, not null
+     * @throws DateTimeException if the specified amount has a non-ISO chronology or
+     *  contains an invalid unit
      * @throws ArithmeticException if numeric overflow occurs
      */
-    public Period minus(Period amountToSubtract) {
+    public Period minus(TemporalAmount amountToSubtract) {
+        Period isoAmount = Period.from(amountToSubtract);
         return create(
-                Math.subtractExact(years, amountToSubtract.years),
-                Math.subtractExact(months, amountToSubtract.months),
-                Math.subtractExact(days, amountToSubtract.days));
+                Math.subtractExact(years, isoAmount.years),
+                Math.subtractExact(months, isoAmount.months),
+                Math.subtractExact(days, isoAmount.days));
     }
 
     /**
@@ -766,8 +806,7 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Returns a copy of this period with the years and months normalized
-     * using a 12 month year.
+     * Returns a copy of this period with the years and months normalized.
      * <p>
      * This normalizes the years and months units, leaving the days unit unchanged.
      * The months unit is adjusted to have an absolute value less than 11,
@@ -778,8 +817,6 @@
      * For example, a period of "1 year and -25 months" will be normalized to
      * "-1 year and -1 month".
      * <p>
-     * This normalization uses a 12 month year which is not valid for all calendar systems.
-     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @return a {@code Period} based on this period with excess months normalized to years, not null
@@ -796,13 +833,11 @@
     }
 
     /**
-     * Gets the total number of months in this period using a 12 month year.
+     * Gets the total number of months in this period.
      * <p>
      * This returns the total number of months in the period by multiplying the
      * number of years by 12 and adding the number of months.
      * <p>
-     * This uses a 12 month year which is not valid for all calendar systems.
-     * <p>
      * This instance is immutable and unaffected by this method call.
      *
      * @return the total number of months in the period, may be negative
@@ -817,6 +852,7 @@
      * <p>
      * This returns a temporal object of the same observable type as the input
      * with this period added.
+     * If the temporal has a chronology, it must be the ISO chronology.
      * <p>
      * In most cases, it is clearer to reverse the calling pattern by using
      * {@link Temporal#plus(TemporalAmount)}.
@@ -826,10 +862,17 @@
      *   dateTime = dateTime.plus(thisPeriod);
      * </pre>
      * <p>
-     * The calculation will add the years, then months, then days.
-     * Only non-zero amounts will be added.
-     * If the date-time has a calendar system with a fixed number of months in a
-     * year, then the years and months will be combined before being added.
+     * The calculation operates as follows.
+     * First, the chronology of the temporal is checked to ensure it is ISO chronology or null.
+     * Second, if the months are zero, the years are added if non-zero, otherwise
+     * the combination of years and months is added if non-zero.
+     * Finally, any days are added.
+     * <p>
+     * This approach ensures that a partial period can be added to a partial date.
+     * For example, a period of years and/or months can be added to a {@code YearMonth},
+     * but a period including days cannot.
+     * The approach also adds years and months together when necessary, which ensures
+     * correct behaviour at the end of the month.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -840,18 +883,15 @@
      */
     @Override
     public Temporal addTo(Temporal temporal) {
-        Objects.requireNonNull(temporal, "temporal");
-        if ((years | months) != 0) {
-            long monthRange = monthRange(temporal);
-            if (monthRange >= 0) {
-                temporal = temporal.plus(years * monthRange + months, MONTHS);
-            } else {
-                if (years != 0) {
-                    temporal = temporal.plus(years, YEARS);
-                }
-                if (months != 0) {
-                    temporal = temporal.plus(months, MONTHS);
-                }
+        validateChrono(temporal);
+        if (months == 0) {
+            if (years != 0) {
+                temporal = temporal.plus(years, YEARS);
+            }
+        } else {
+            long totalMonths = toTotalMonths();
+            if (totalMonths != 0) {
+                temporal = temporal.plus(totalMonths, MONTHS);
             }
         }
         if (days != 0) {
@@ -865,6 +905,7 @@
      * <p>
      * This returns a temporal object of the same observable type as the input
      * with this period subtracted.
+     * If the temporal has a chronology, it must be the ISO chronology.
      * <p>
      * In most cases, it is clearer to reverse the calling pattern by using
      * {@link Temporal#minus(TemporalAmount)}.
@@ -874,10 +915,17 @@
      *   dateTime = dateTime.minus(thisPeriod);
      * </pre>
      * <p>
-     * The calculation will subtract the years, then months, then days.
-     * Only non-zero amounts will be subtracted.
-     * If the date-time has a calendar system with a fixed number of months in a
-     * year, then the years and months will be combined before being subtracted.
+     * The calculation operates as follows.
+     * First, the chronology of the temporal is checked to ensure it is ISO chronology or null.
+     * Second, if the months are zero, the years are subtracted if non-zero, otherwise
+     * the combination of years and months is subtracted if non-zero.
+     * Finally, any days are subtracted.
+     * <p>
+     * This approach ensures that a partial period can be subtracted from a partial date.
+     * For example, a period of years and/or months can be subtracted from a {@code YearMonth},
+     * but a period including days cannot.
+     * The approach also subtracts years and months together when necessary, which ensures
+     * correct behaviour at the end of the month.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
@@ -888,18 +936,15 @@
      */
     @Override
     public Temporal subtractFrom(Temporal temporal) {
-        Objects.requireNonNull(temporal, "temporal");
-        if ((years | months) != 0) {
-            long monthRange = monthRange(temporal);
-            if (monthRange >= 0) {
-                temporal = temporal.minus(years * monthRange + months, MONTHS);
-            } else {
-                if (years != 0) {
-                    temporal = temporal.minus(years, YEARS);
-                }
-                if (months != 0) {
-                    temporal = temporal.minus(months, MONTHS);
-                }
+        validateChrono(temporal);
+        if (months == 0) {
+            if (years != 0) {
+                temporal = temporal.minus(years, YEARS);
+            }
+        } else {
+            long totalMonths = toTotalMonths();
+            if (totalMonths != 0) {
+                temporal = temporal.minus(totalMonths, MONTHS);
             }
         }
         if (days != 0) {
@@ -909,26 +954,21 @@
     }
 
     /**
-     * Calculates the range of months based on the temporal.
-     *
-     * @param temporal  the temporal, not null
-     * @return the month range, negative if not fixed range
+     * Validates that the temporal has the correct chronology.
      */
-    private long monthRange(Temporal temporal) {
-        if (temporal.isSupported(MONTH_OF_YEAR)) {
-            ValueRange startRange = Chronology.from(temporal).range(MONTH_OF_YEAR);
-            if (startRange.isFixed() && startRange.isIntValue()) {
-                return startRange.getMaximum() - startRange.getMinimum() + 1;
-            }
+    private void validateChrono(TemporalAccessor temporal) {
+        Objects.requireNonNull(temporal, "temporal");
+        Chronology temporalChrono = temporal.query(TemporalQuery.chronology());
+        if (temporalChrono != null && IsoChronology.INSTANCE.equals(temporalChrono) == false) {
+            throw new DateTimeException("Chronology mismatch, expected: ISO, actual: " + temporalChrono.getId());
         }
-        return -1;
     }
 
     //-----------------------------------------------------------------------
     /**
      * Checks if this period is equal to another period.
      * <p>
-     * The comparison is based on the amounts held in the period.
+     * The comparison is based on the type {@code Period} and each of the three amounts.
      * To be equal, the years, months and days units must be individually equal.
      * Note that this means that a period of "15 Months" is not equal to a period
      * of "1 Year and 3 Months".
--- a/src/share/classes/java/time/Year.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/Year.java	Tue Oct 08 14:57:32 2013 -0700
@@ -242,6 +242,7 @@
         if (temporal instanceof Year) {
             return (Year) temporal;
         }
+        Objects.requireNonNull(temporal, "temporal");
         try {
             if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
                 temporal = LocalDate.from(temporal);
@@ -859,7 +860,8 @@
      * 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}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code Year} using {@link #from(TemporalAccessor)}.
      * For example, the period in decades between two year can be calculated
      * using {@code startYear.until(endYear, DECADES)}.
      * <p>
@@ -885,25 +887,22 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endYear  the end year, which must be a {@code Year}, not null
+     * @param endExclusive  the end date, exclusive, which is converted to a {@code Year}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to a {@code Year}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endYear, TemporalUnit unit) {
-        if (endYear instanceof Year == false) {
-            Objects.requireNonNull(endYear, "endYear");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
-        Year end = (Year) endYear;
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        Year end = Year.from(endExclusive);
         if (unit instanceof ChronoUnit) {
             long yearsUntil = ((long) end.year) - year;  // no overflow
             switch ((ChronoUnit) unit) {
@@ -915,7 +914,7 @@
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
-        return unit.between(this, endYear);
+        return unit.between(this, end);
     }
 
     /**
--- a/src/share/classes/java/time/YearMonth.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/YearMonth.java	Tue Oct 08 14:57:32 2013 -0700
@@ -245,6 +245,7 @@
         if (temporal instanceof YearMonth) {
             return (YearMonth) temporal;
         }
+        Objects.requireNonNull(temporal, "temporal");
         try {
             if (IsoChronology.INSTANCE.equals(Chronology.from(temporal)) == false) {
                 temporal = LocalDate.from(temporal);
@@ -992,7 +993,8 @@
      * 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}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code YearMonth} using {@link #from(TemporalAccessor)}.
      * For example, the period in years between two year-months can be calculated
      * using {@code startYearMonth.until(endYearMonth, YEARS)}.
      * <p>
@@ -1018,25 +1020,22 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * 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 endExclusive  the end date, exclusive, which is converted to a {@code YearMonth}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to a {@code YearMonth}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endYearMonth, TemporalUnit unit) {
-        if (endYearMonth instanceof YearMonth == false) {
-            Objects.requireNonNull(endYearMonth, "endYearMonth");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
-        YearMonth end = (YearMonth) endYearMonth;
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        YearMonth end = YearMonth.from(endExclusive);
         if (unit instanceof ChronoUnit) {
             long monthsUntil = end.getProlepticMonth() - getProlepticMonth();  // no overflow
             switch ((ChronoUnit) unit) {
@@ -1049,7 +1048,7 @@
             }
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
-        return unit.between(this, endYearMonth);
+        return unit.between(this, end);
     }
 
     /**
--- a/src/share/classes/java/time/ZoneOffset.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/ZoneOffset.java	Tue Oct 08 14:57:32 2013 -0700
@@ -333,6 +333,7 @@
      * @throws DateTimeException if unable to convert to an {@code ZoneOffset}
      */
     public static ZoneOffset from(TemporalAccessor temporal) {
+        Objects.requireNonNull(temporal, "temporal");
         ZoneOffset offset = temporal.query(TemporalQuery.offset());
         if (offset == null) {
             throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + temporal.getClass());
--- a/src/share/classes/java/time/ZonedDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/ZonedDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1540,6 +1540,11 @@
      */
     @Override
     public ZonedDateTime plus(TemporalAmount amountToAdd) {
+        if (amountToAdd instanceof Period) {
+            Period periodToAdd = (Period) amountToAdd;
+            return resolveLocal(dateTime.plus(periodToAdd));
+        }
+        Objects.requireNonNull(amountToAdd, "amountToAdd");
         return (ZonedDateTime) amountToAdd.addTo(this);
     }
 
@@ -1787,6 +1792,11 @@
      */
     @Override
     public ZonedDateTime minus(TemporalAmount amountToSubtract) {
+        if (amountToSubtract instanceof Period) {
+            Period periodToSubtract = (Period) amountToSubtract;
+            return resolveLocal(dateTime.minus(periodToSubtract));
+        }
+        Objects.requireNonNull(amountToSubtract, "amountToSubtract");
         return (ZonedDateTime) amountToSubtract.subtractFrom(this);
     }
 
@@ -2034,7 +2044,8 @@
      * For example, the period in days between two date-times can be calculated
      * using {@code startDateTime.until(endDateTime, DAYS)}.
      * <p>
-     * The {@code Temporal} passed to this method must be a {@code ZonedDateTime}.
+     * The {@code Temporal} passed to this method is converted to a
+     * {@code ZonedDateTime} using {@link #from(TemporalAccessor)}.
      * If the time-zone differs between the two zoned date-times, the specified
      * end date-time is normalized to have the same zone as this date-time.
      * <p>
@@ -2076,26 +2087,23 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
-     * the second argument.
+     * passing {@code this} as the first argument and the converted input temporal
+     * as the second argument.
      * <p>
      * 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 endExclusive  the end date, exclusive, which is converted to a {@code ZonedDateTime}, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to a {@code ZonedDateTime}
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override
-    public long until(Temporal endDateTime, TemporalUnit unit) {
-        if (endDateTime instanceof ZonedDateTime == false) {
-            Objects.requireNonNull(endDateTime, "endDateTime");
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        ZonedDateTime end = ZonedDateTime.from(endExclusive);
         if (unit instanceof ChronoUnit) {
-            ZonedDateTime end = (ZonedDateTime) endDateTime;
             end = end.withZoneSameInstant(zone);
             if (unit.isDateBased()) {
                 return dateTime.until(end.dateTime, unit);
@@ -2103,7 +2111,7 @@
                 return toOffsetDateTime().until(end.toOffsetDateTime(), unit);
             }
         }
-        return unit.between(this, endDateTime);
+        return unit.between(this, end);
     }
 
     /**
--- a/src/share/classes/java/time/chrono/ChronoDateImpl.java	Tue Oct 08 14:53:14 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,455 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * Copyright (c) 2012, 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 java.time.chrono;
-
-import static java.time.temporal.ChronoField.DAY_OF_MONTH;
-import static java.time.temporal.ChronoField.ERA;
-import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
-import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
-import static java.time.temporal.ChronoField.YEAR_OF_ERA;
-
-import java.io.Serializable;
-import java.time.DateTimeException;
-import java.time.temporal.ChronoUnit;
-import java.time.temporal.Temporal;
-import java.time.temporal.TemporalAdjuster;
-import java.time.temporal.TemporalAmount;
-import java.time.temporal.TemporalField;
-import java.time.temporal.TemporalUnit;
-import java.time.temporal.UnsupportedTemporalTypeException;
-import java.time.temporal.ValueRange;
-import java.util.Objects;
-
-/**
- * A date expressed in terms of a standard year-month-day calendar system.
- * <p>
- * This class is used by applications seeking to handle dates in non-ISO calendar systems.
- * For example, the Japanese, Minguo, Thai Buddhist and others.
- * <p>
- * {@code ChronoLocalDate} is built on the generic concepts of year, month and day.
- * The calendar system, represented by a {@link java.time.chrono.Chronology}, expresses the relationship between
- * the fields and this class allows the resulting date to be manipulated.
- * <p>
- * Note that not all calendar systems are suitable for use with this class.
- * For example, the Mayan calendar uses a system that bears no relation to years, months and days.
- * <p>
- * The API design encourages the use of {@code LocalDate} for the majority of the application.
- * This includes code to read and write from a persistent data store, such as a database,
- * and to send dates and times across a network. The {@code ChronoLocalDate} instance is then used
- * at the user interface level to deal with localized input/output.
- *
- * <P>Example: </p>
- * <pre>
- *        System.out.printf("Example()%n");
- *        // Enumerate the list of available calendars and print today for each
- *        Set&lt;Chronology&gt; chronos = Chronology.getAvailableChronologies();
- *        for (Chronology chrono : chronos) {
- *            ChronoLocalDate date = chrono.dateNow();
- *            System.out.printf("   %20s: %s%n", chrono.getID(), date.toString());
- *        }
- *
- *        // Print the Hijrah date and calendar
- *        ChronoLocalDate date = Chronology.of("Hijrah").dateNow();
- *        int day = date.get(ChronoField.DAY_OF_MONTH);
- *        int dow = date.get(ChronoField.DAY_OF_WEEK);
- *        int month = date.get(ChronoField.MONTH_OF_YEAR);
- *        int year = date.get(ChronoField.YEAR);
- *        System.out.printf("  Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
- *                dow, day, month, year);
-
- *        // Print today's date and the last day of the year
- *        ChronoLocalDate now1 = Chronology.of("Hijrah").dateNow();
- *        ChronoLocalDate first = now1.with(ChronoField.DAY_OF_MONTH, 1)
- *                .with(ChronoField.MONTH_OF_YEAR, 1);
- *        ChronoLocalDate last = first.plus(1, ChronoUnit.YEARS)
- *                .minus(1, ChronoUnit.DAYS);
- *        System.out.printf("  Today is %s: start: %s; end: %s%n", last.getChronology().getID(),
- *                first, last);
- * </pre>
- *
- * <h3>Adding Calendars</h3>
- * <p> The set of calendars is extensible by defining a subclass of {@link ChronoLocalDate}
- * to represent a date instance and an implementation of {@code Chronology}
- * to be the factory for the ChronoLocalDate subclass.
- * </p>
- * <p> To permit the discovery of the additional calendar types the implementation of
- * {@code Chronology} must be registered as a Service implementing the {@code Chronology} interface
- * in the {@code META-INF/Services} file as per the specification of {@link java.util.ServiceLoader}.
- * 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>
- *
- * @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.
- *
- * @param <D> the ChronoLocalDate of this date-time
- * @since 1.8
- */
-abstract class ChronoDateImpl<D extends ChronoLocalDate>
-        implements ChronoLocalDate, Temporal, TemporalAdjuster, Serializable {
-
-    /**
-     * Serialization version.
-     */
-    private static final long serialVersionUID = 6282433883239719096L;
-
-    /**
-     * Casts the {@code Temporal} to {@code ChronoLocalDate} ensuring it bas the specified chronology.
-     *
-     * @param chrono  the chronology to check for, not null
-     * @param temporal  a date-time to cast, not null
-     * @return the date-time checked and cast to {@code ChronoLocalDate}, not null
-     * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate
-     *  or the chronology is not equal this Chronology
-     */
-    static <D extends ChronoLocalDate> D ensureValid(Chronology chrono, Temporal temporal) {
-        @SuppressWarnings("unchecked")
-        D other = (D) temporal;
-        if (chrono.equals(other.getChronology()) == false) {
-            throw new ClassCastException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + other.getChronology().getId());
-        }
-        return other;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Creates an instance.
-     */
-    ChronoDateImpl() {
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public D with(TemporalAdjuster adjuster) {
-        return (D) ChronoLocalDate.super.with(adjuster);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public D with(TemporalField field, long value) {
-        return (D) ChronoLocalDate.super.with(field, value);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    @SuppressWarnings("unchecked")
-    public D plus(TemporalAmount amount) {
-        return (D) ChronoLocalDate.super.plus(amount);
-    }
-
-    //-----------------------------------------------------------------------
-    @Override
-    @SuppressWarnings("unchecked")
-    public D plus(long amountToAdd, TemporalUnit unit) {
-        if (unit instanceof ChronoUnit) {
-            ChronoUnit f = (ChronoUnit) unit;
-            switch (f) {
-                case DAYS: return plusDays(amountToAdd);
-                case WEEKS: return plusDays(Math.multiplyExact(amountToAdd, 7));
-                case MONTHS: return plusMonths(amountToAdd);
-                case YEARS: return plusYears(amountToAdd);
-                case DECADES: return plusYears(Math.multiplyExact(amountToAdd, 10));
-                case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100));
-                case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));
-                case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));
-            }
-            throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
-        }
-        return (D) ChronoLocalDate.super.plus(amountToAdd, unit);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public D minus(TemporalAmount amount) {
-        return (D) ChronoLocalDate.super.minus(amount);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public D minus(long amountToSubtract, TemporalUnit unit) {
-        return (D) ChronoLocalDate.super.minus(amountToSubtract, unit);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this date with the specified period in years added.
-     * <p>
-     * This adds the specified period in years to the date.
-     * In some cases, adding years can cause the resulting date to become invalid.
-     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
-     * that the result is valid. Typically this will select the last valid day of the month.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param yearsToAdd  the years to add, may be negative
-     * @return a date based on this one with the years added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    abstract D plusYears(long yearsToAdd);
-
-    /**
-     * Returns a copy of this date with the specified period in months added.
-     * <p>
-     * This adds the specified period in months to the date.
-     * In some cases, adding months can cause the resulting date to become invalid.
-     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
-     * that the result is valid. Typically this will select the last valid day of the month.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param monthsToAdd  the months to add, may be negative
-     * @return a date based on this one with the months added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    abstract D plusMonths(long monthsToAdd);
-
-    /**
-     * Returns a copy of this date with the specified period in weeks added.
-     * <p>
-     * This adds the specified period in weeks to the date.
-     * In some cases, adding weeks can cause the resulting date to become invalid.
-     * If this occurs, then other fields will be adjusted to ensure that the result is valid.
-     * <p>
-     * The default implementation uses {@link #plusDays(long)} using a 7 day week.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param weeksToAdd  the weeks to add, may be negative
-     * @return a date based on this one with the weeks added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    D plusWeeks(long weeksToAdd) {
-        return plusDays(Math.multiplyExact(weeksToAdd, 7));
-    }
-
-    /**
-     * Returns a copy of this date with the specified number of days added.
-     * <p>
-     * This adds the specified period in days to the date.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param daysToAdd  the days to add, may be negative
-     * @return a date based on this one with the days added, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    abstract D plusDays(long daysToAdd);
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns a copy of this date with the specified period in years subtracted.
-     * <p>
-     * This subtracts the specified period in years to the date.
-     * In some cases, subtracting years can cause the resulting date to become invalid.
-     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
-     * that the result is valid. Typically this will select the last valid day of the month.
-     * <p>
-     * The default implementation uses {@link #plusYears(long)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param yearsToSubtract  the years to subtract, may be negative
-     * @return a date based on this one with the years subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    @SuppressWarnings("unchecked")
-    D minusYears(long yearsToSubtract) {
-        return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract));
-    }
-
-    /**
-     * Returns a copy of this date with the specified period in months subtracted.
-     * <p>
-     * This subtracts the specified period in months to the date.
-     * In some cases, subtracting months can cause the resulting date to become invalid.
-     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
-     * that the result is valid. Typically this will select the last valid day of the month.
-     * <p>
-     * The default implementation uses {@link #plusMonths(long)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param monthsToSubtract  the months to subtract, may be negative
-     * @return a date based on this one with the months subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    @SuppressWarnings("unchecked")
-    D minusMonths(long monthsToSubtract) {
-        return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract));
-    }
-
-    /**
-     * Returns a copy of this date with the specified period in weeks subtracted.
-     * <p>
-     * This subtracts the specified period in weeks to the date.
-     * In some cases, subtracting weeks can cause the resulting date to become invalid.
-     * If this occurs, then other fields will be adjusted to ensure that the result is valid.
-     * <p>
-     * The default implementation uses {@link #plusWeeks(long)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param weeksToSubtract  the weeks to subtract, may be negative
-     * @return a date based on this one with the weeks subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    @SuppressWarnings("unchecked")
-    D minusWeeks(long weeksToSubtract) {
-        return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract));
-    }
-
-    /**
-     * Returns a copy of this date with the specified number of days subtracted.
-     * <p>
-     * This subtracts the specified period in days to the date.
-     * <p>
-     * The default implementation uses {@link #plusDays(long)}.
-     * <p>
-     * This instance is immutable and unaffected by this method call.
-     *
-     * @param daysToSubtract  the days to subtract, may be negative
-     * @return a date based on this one with the days subtracted, not null
-     * @throws DateTimeException if the result exceeds the supported date range
-     */
-    @SuppressWarnings("unchecked")
-    D minusDays(long daysToSubtract) {
-        return (daysToSubtract == Long.MIN_VALUE ? ((ChronoDateImpl<D>)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract));
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * {@inheritDoc}
-     * @throws DateTimeException {@inheritDoc}
-     * @throws ArithmeticException {@inheritDoc}
-     */
-    @Override
-    public long until(Temporal endDateTime, TemporalUnit unit) {
-        Objects.requireNonNull(endDateTime, "endDateTime");
-        Objects.requireNonNull(unit, "unit");
-        if (endDateTime instanceof ChronoLocalDate == false) {
-            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 amount as objects have different chronologies");
-        }
-        if (unit instanceof ChronoUnit) {
-            switch ((ChronoUnit) unit) {
-                case DAYS: return daysUntil(end);
-                case WEEKS: return daysUntil(end) / 7;
-                case MONTHS: return monthsUntil(end);
-                case YEARS: return monthsUntil(end) / 12;
-                case DECADES: return monthsUntil(end) / 120;
-                case CENTURIES: return monthsUntil(end) / 1200;
-                case MILLENNIA: return monthsUntil(end) / 12000;
-                case ERAS: return end.getLong(ERA) - getLong(ERA);
-            }
-            throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
-        }
-        return unit.between(this, endDateTime);
-    }
-
-    private long daysUntil(ChronoLocalDate end) {
-        return end.toEpochDay() - toEpochDay();  // no overflow
-    }
-
-    private long monthsUntil(ChronoLocalDate end) {
-        ValueRange range = getChronology().range(MONTH_OF_YEAR);
-        if (range.getMaximum() != 12) {
-            throw new IllegalStateException("ChronoDateImpl only supports Chronologies with 12 months per year");
-        }
-        long packed1 = getLong(PROLEPTIC_MONTH) * 32L + get(DAY_OF_MONTH);  // no overflow
-        long packed2 = end.getLong(PROLEPTIC_MONTH) * 32L + end.get(DAY_OF_MONTH);  // no overflow
-        return (packed2 - packed1) / 32;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof ChronoLocalDate) {
-            return compareTo((ChronoLocalDate) obj) == 0;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        long epDay = toEpochDay();
-        return getChronology().hashCode() ^ ((int) (epDay ^ (epDay >>> 32)));
-    }
-
-    @Override
-    public String toString() {
-        // getLong() reduces chances of exceptions in toString()
-        long yoe = getLong(YEAR_OF_ERA);
-        long moy = getLong(MONTH_OF_YEAR);
-        long dom = getLong(DAY_OF_MONTH);
-        StringBuilder buf = new StringBuilder(30);
-        buf.append(getChronology().toString())
-                .append(" ")
-                .append(getEra())
-                .append(" ")
-                .append(yoe)
-                .append(moy < 10 ? "-0" : "-").append(moy)
-                .append(dom < 10 ? "-0" : "-").append(dom);
-        return buf.toString();
-    }
-
-}
--- a/src/share/classes/java/time/chrono/ChronoLocalDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/ChronoLocalDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -69,7 +69,6 @@
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.time.Period;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
@@ -292,6 +291,7 @@
         if (temporal instanceof ChronoLocalDate) {
             return (ChronoLocalDate) temporal;
         }
+        Objects.requireNonNull(temporal, "temporal");
         Chronology chrono = temporal.query(TemporalQuery.chronology());
         if (chrono == null) {
             throw new DateTimeException("Unable to obtain ChronoLocalDate from TemporalAccessor: " + temporal.getClass());
@@ -428,7 +428,7 @@
      */
     @Override
     default ChronoLocalDate with(TemporalAdjuster adjuster) {
-        return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster));
+        return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.with(adjuster));
     }
 
     /**
@@ -442,7 +442,7 @@
         if (field instanceof ChronoField) {
             throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
         }
-        return ChronoDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue));
+        return ChronoLocalDateImpl.ensureValid(getChronology(), field.adjustInto(this, newValue));
     }
 
     /**
@@ -452,7 +452,7 @@
      */
     @Override
     default ChronoLocalDate plus(TemporalAmount amount) {
-        return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount));
+        return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.plus(amount));
     }
 
     /**
@@ -465,7 +465,7 @@
         if (unit instanceof ChronoUnit) {
             throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
         }
-        return ChronoDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd));
+        return ChronoLocalDateImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd));
     }
 
     /**
@@ -475,7 +475,7 @@
      */
     @Override
     default ChronoLocalDate minus(TemporalAmount amount) {
-        return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount));
+        return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amount));
     }
 
     /**
@@ -486,7 +486,7 @@
      */
     @Override
     default ChronoLocalDate minus(long amountToSubtract, TemporalUnit unit) {
-        return ChronoDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit));
+        return ChronoLocalDateImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit));
     }
 
     //-----------------------------------------------------------------------
@@ -561,8 +561,8 @@
      * 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 {@code Temporal} passed to this method is converted to a
+     * {@code ChronoLocalDate} using {@link Chronology#date(TemporalAccessor)}.
      * The calculation returns a whole number, representing the number of
      * complete units between the two dates.
      * For example, the amount in days between two dates can be calculated
@@ -586,25 +586,30 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
+     * passing {@code this} as the first argument and the converted input temporal as
      * the second argument.
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endDate  the end date, which must be a {@code ChronoLocalDate}
-     *  in the same chronology, not null
+     * @param endExclusive  the end date, exclusive, which is converted to a
+     *  {@code ChronoLocalDate} in the same chronology, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to a {@code ChronoLocalDate}
+     * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
     @Override  // override for Javadoc
-    long until(Temporal endDate, TemporalUnit unit);
+    long until(Temporal endExclusive, TemporalUnit unit);
 
     /**
-     * Calculates the period between this date and another date as a {@code Period}.
+     * Calculates the period between this date and another date as a {@code ChronoPeriod}.
      * <p>
-     * This calculates the period between two dates in terms of years, months and days.
+     * This calculates the period between two dates. All supplied chronologies
+     * calculate the period using years, months and days, however the
+     * {@code ChronoPeriod} API allows the period to be represented using other units.
+     * <p>
      * 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 negative sign will be the same in each of year, month and day.
@@ -614,12 +619,12 @@
      * <p>
      * This instance is immutable and unaffected by this method call.
      *
-     * @param endDate  the end date, exclusive, which may be in any chronology, not null
+     * @param endDateExclusive  the end date, exclusive, which may be in any chronology, not null
      * @return the period between this date and the end date, not null
      * @throws DateTimeException if the period cannot be calculated
      * @throws ArithmeticException if numeric overflow occurs
      */
-    Period until(ChronoLocalDate endDate);
+    ChronoPeriod until(ChronoLocalDate endDateExclusive);
 
     /**
      * Formats this date using the specified formatter.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/time/chrono/ChronoLocalDateImpl.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,444 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2012, 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 java.time.chrono;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.ERA;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
+import static java.time.temporal.ChronoField.YEAR_OF_ERA;
+
+import java.io.Serializable;
+import java.time.DateTimeException;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAdjuster;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+import java.time.temporal.ValueRange;
+import java.util.Objects;
+
+/**
+ * A date expressed in terms of a standard year-month-day calendar system.
+ * <p>
+ * This class is used by applications seeking to handle dates in non-ISO calendar systems.
+ * For example, the Japanese, Minguo, Thai Buddhist and others.
+ * <p>
+ * {@code ChronoLocalDate} is built on the generic concepts of year, month and day.
+ * The calendar system, represented by a {@link java.time.chrono.Chronology}, expresses the relationship between
+ * the fields and this class allows the resulting date to be manipulated.
+ * <p>
+ * Note that not all calendar systems are suitable for use with this class.
+ * For example, the Mayan calendar uses a system that bears no relation to years, months and days.
+ * <p>
+ * The API design encourages the use of {@code LocalDate} for the majority of the application.
+ * This includes code to read and write from a persistent data store, such as a database,
+ * and to send dates and times across a network. The {@code ChronoLocalDate} instance is then used
+ * at the user interface level to deal with localized input/output.
+ *
+ * <P>Example: </p>
+ * <pre>
+ *        System.out.printf("Example()%n");
+ *        // Enumerate the list of available calendars and print today for each
+ *        Set&lt;Chronology&gt; chronos = Chronology.getAvailableChronologies();
+ *        for (Chronology chrono : chronos) {
+ *            ChronoLocalDate date = chrono.dateNow();
+ *            System.out.printf("   %20s: %s%n", chrono.getID(), date.toString());
+ *        }
+ *
+ *        // Print the Hijrah date and calendar
+ *        ChronoLocalDate date = Chronology.of("Hijrah").dateNow();
+ *        int day = date.get(ChronoField.DAY_OF_MONTH);
+ *        int dow = date.get(ChronoField.DAY_OF_WEEK);
+ *        int month = date.get(ChronoField.MONTH_OF_YEAR);
+ *        int year = date.get(ChronoField.YEAR);
+ *        System.out.printf("  Today is %s %s %d-%s-%d%n", date.getChronology().getID(),
+ *                dow, day, month, year);
+
+ *        // Print today's date and the last day of the year
+ *        ChronoLocalDate now1 = Chronology.of("Hijrah").dateNow();
+ *        ChronoLocalDate first = now1.with(ChronoField.DAY_OF_MONTH, 1)
+ *                .with(ChronoField.MONTH_OF_YEAR, 1);
+ *        ChronoLocalDate last = first.plus(1, ChronoUnit.YEARS)
+ *                .minus(1, ChronoUnit.DAYS);
+ *        System.out.printf("  Today is %s: start: %s; end: %s%n", last.getChronology().getID(),
+ *                first, last);
+ * </pre>
+ *
+ * <h3>Adding Calendars</h3>
+ * <p> The set of calendars is extensible by defining a subclass of {@link ChronoLocalDate}
+ * to represent a date instance and an implementation of {@code Chronology}
+ * to be the factory for the ChronoLocalDate subclass.
+ * </p>
+ * <p> To permit the discovery of the additional calendar types the implementation of
+ * {@code Chronology} must be registered as a Service implementing the {@code Chronology} interface
+ * in the {@code META-INF/Services} file as per the specification of {@link java.util.ServiceLoader}.
+ * 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>
+ *
+ * @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.
+ *
+ * @param <D> the ChronoLocalDate of this date-time
+ * @since 1.8
+ */
+abstract class ChronoLocalDateImpl<D extends ChronoLocalDate>
+        implements ChronoLocalDate, Temporal, TemporalAdjuster, Serializable {
+
+    /**
+     * Serialization version.
+     */
+    private static final long serialVersionUID = 6282433883239719096L;
+
+    /**
+     * Casts the {@code Temporal} to {@code ChronoLocalDate} ensuring it bas the specified chronology.
+     *
+     * @param chrono  the chronology to check for, not null
+     * @param temporal  a date-time to cast, not null
+     * @return the date-time checked and cast to {@code ChronoLocalDate}, not null
+     * @throws ClassCastException if the date-time cannot be cast to ChronoLocalDate
+     *  or the chronology is not equal this Chronology
+     */
+    static <D extends ChronoLocalDate> D ensureValid(Chronology chrono, Temporal temporal) {
+        @SuppressWarnings("unchecked")
+        D other = (D) temporal;
+        if (chrono.equals(other.getChronology()) == false) {
+            throw new ClassCastException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + other.getChronology().getId());
+        }
+        return other;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Creates an instance.
+     */
+    ChronoLocalDateImpl() {
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public D with(TemporalAdjuster adjuster) {
+        return (D) ChronoLocalDate.super.with(adjuster);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public D with(TemporalField field, long value) {
+        return (D) ChronoLocalDate.super.with(field, value);
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    @SuppressWarnings("unchecked")
+    public D plus(TemporalAmount amount) {
+        return (D) ChronoLocalDate.super.plus(amount);
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    @SuppressWarnings("unchecked")
+    public D plus(long amountToAdd, TemporalUnit unit) {
+        if (unit instanceof ChronoUnit) {
+            ChronoUnit f = (ChronoUnit) unit;
+            switch (f) {
+                case DAYS: return plusDays(amountToAdd);
+                case WEEKS: return plusDays(Math.multiplyExact(amountToAdd, 7));
+                case MONTHS: return plusMonths(amountToAdd);
+                case YEARS: return plusYears(amountToAdd);
+                case DECADES: return plusYears(Math.multiplyExact(amountToAdd, 10));
+                case CENTURIES: return plusYears(Math.multiplyExact(amountToAdd, 100));
+                case MILLENNIA: return plusYears(Math.multiplyExact(amountToAdd, 1000));
+                case ERAS: return with(ERA, Math.addExact(getLong(ERA), amountToAdd));
+            }
+            throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
+        }
+        return (D) ChronoLocalDate.super.plus(amountToAdd, unit);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public D minus(TemporalAmount amount) {
+        return (D) ChronoLocalDate.super.minus(amount);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public D minus(long amountToSubtract, TemporalUnit unit) {
+        return (D) ChronoLocalDate.super.minus(amountToSubtract, unit);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a copy of this date with the specified period in years added.
+     * <p>
+     * This adds the specified period in years to the date.
+     * In some cases, adding years can cause the resulting date to become invalid.
+     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
+     * that the result is valid. Typically this will select the last valid day of the month.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param yearsToAdd  the years to add, may be negative
+     * @return a date based on this one with the years added, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    abstract D plusYears(long yearsToAdd);
+
+    /**
+     * Returns a copy of this date with the specified period in months added.
+     * <p>
+     * This adds the specified period in months to the date.
+     * In some cases, adding months can cause the resulting date to become invalid.
+     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
+     * that the result is valid. Typically this will select the last valid day of the month.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param monthsToAdd  the months to add, may be negative
+     * @return a date based on this one with the months added, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    abstract D plusMonths(long monthsToAdd);
+
+    /**
+     * Returns a copy of this date with the specified period in weeks added.
+     * <p>
+     * This adds the specified period in weeks to the date.
+     * In some cases, adding weeks can cause the resulting date to become invalid.
+     * If this occurs, then other fields will be adjusted to ensure that the result is valid.
+     * <p>
+     * The default implementation uses {@link #plusDays(long)} using a 7 day week.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param weeksToAdd  the weeks to add, may be negative
+     * @return a date based on this one with the weeks added, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    D plusWeeks(long weeksToAdd) {
+        return plusDays(Math.multiplyExact(weeksToAdd, 7));
+    }
+
+    /**
+     * Returns a copy of this date with the specified number of days added.
+     * <p>
+     * This adds the specified period in days to the date.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param daysToAdd  the days to add, may be negative
+     * @return a date based on this one with the days added, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    abstract D plusDays(long daysToAdd);
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a copy of this date with the specified period in years subtracted.
+     * <p>
+     * This subtracts the specified period in years to the date.
+     * In some cases, subtracting years can cause the resulting date to become invalid.
+     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
+     * that the result is valid. Typically this will select the last valid day of the month.
+     * <p>
+     * The default implementation uses {@link #plusYears(long)}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param yearsToSubtract  the years to subtract, may be negative
+     * @return a date based on this one with the years subtracted, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    @SuppressWarnings("unchecked")
+    D minusYears(long yearsToSubtract) {
+        return (yearsToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl<D>)plusYears(Long.MAX_VALUE)).plusYears(1) : plusYears(-yearsToSubtract));
+    }
+
+    /**
+     * Returns a copy of this date with the specified period in months subtracted.
+     * <p>
+     * This subtracts the specified period in months to the date.
+     * In some cases, subtracting months can cause the resulting date to become invalid.
+     * If this occurs, then other fields, typically the day-of-month, will be adjusted to ensure
+     * that the result is valid. Typically this will select the last valid day of the month.
+     * <p>
+     * The default implementation uses {@link #plusMonths(long)}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param monthsToSubtract  the months to subtract, may be negative
+     * @return a date based on this one with the months subtracted, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    @SuppressWarnings("unchecked")
+    D minusMonths(long monthsToSubtract) {
+        return (monthsToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl<D>)plusMonths(Long.MAX_VALUE)).plusMonths(1) : plusMonths(-monthsToSubtract));
+    }
+
+    /**
+     * Returns a copy of this date with the specified period in weeks subtracted.
+     * <p>
+     * This subtracts the specified period in weeks to the date.
+     * In some cases, subtracting weeks can cause the resulting date to become invalid.
+     * If this occurs, then other fields will be adjusted to ensure that the result is valid.
+     * <p>
+     * The default implementation uses {@link #plusWeeks(long)}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param weeksToSubtract  the weeks to subtract, may be negative
+     * @return a date based on this one with the weeks subtracted, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    @SuppressWarnings("unchecked")
+    D minusWeeks(long weeksToSubtract) {
+        return (weeksToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl<D>)plusWeeks(Long.MAX_VALUE)).plusWeeks(1) : plusWeeks(-weeksToSubtract));
+    }
+
+    /**
+     * Returns a copy of this date with the specified number of days subtracted.
+     * <p>
+     * This subtracts the specified period in days to the date.
+     * <p>
+     * The default implementation uses {@link #plusDays(long)}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param daysToSubtract  the days to subtract, may be negative
+     * @return a date based on this one with the days subtracted, not null
+     * @throws DateTimeException if the result exceeds the supported date range
+     */
+    @SuppressWarnings("unchecked")
+    D minusDays(long daysToSubtract) {
+        return (daysToSubtract == Long.MIN_VALUE ? ((ChronoLocalDateImpl<D>)plusDays(Long.MAX_VALUE)).plusDays(1) : plusDays(-daysToSubtract));
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        Objects.requireNonNull(endExclusive, "endExclusive");
+        ChronoLocalDate end = getChronology().date(endExclusive);
+        if (unit instanceof ChronoUnit) {
+            switch ((ChronoUnit) unit) {
+                case DAYS: return daysUntil(end);
+                case WEEKS: return daysUntil(end) / 7;
+                case MONTHS: return monthsUntil(end);
+                case YEARS: return monthsUntil(end) / 12;
+                case DECADES: return monthsUntil(end) / 120;
+                case CENTURIES: return monthsUntil(end) / 1200;
+                case MILLENNIA: return monthsUntil(end) / 12000;
+                case ERAS: return end.getLong(ERA) - getLong(ERA);
+            }
+            throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
+        }
+        Objects.requireNonNull(unit, "unit");
+        return unit.between(this, end);
+    }
+
+    private long daysUntil(ChronoLocalDate end) {
+        return end.toEpochDay() - toEpochDay();  // no overflow
+    }
+
+    private long monthsUntil(ChronoLocalDate end) {
+        ValueRange range = getChronology().range(MONTH_OF_YEAR);
+        if (range.getMaximum() != 12) {
+            throw new IllegalStateException("ChronoLocalDateImpl only supports Chronologies with 12 months per year");
+        }
+        long packed1 = getLong(PROLEPTIC_MONTH) * 32L + get(DAY_OF_MONTH);  // no overflow
+        long packed2 = end.getLong(PROLEPTIC_MONTH) * 32L + end.get(DAY_OF_MONTH);  // no overflow
+        return (packed2 - packed1) / 32;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ChronoLocalDate) {
+            return compareTo((ChronoLocalDate) obj) == 0;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        long epDay = toEpochDay();
+        return getChronology().hashCode() ^ ((int) (epDay ^ (epDay >>> 32)));
+    }
+
+    @Override
+    public String toString() {
+        // getLong() reduces chances of exceptions in toString()
+        long yoe = getLong(YEAR_OF_ERA);
+        long moy = getLong(MONTH_OF_YEAR);
+        long dom = getLong(DAY_OF_MONTH);
+        StringBuilder buf = new StringBuilder(30);
+        buf.append(getChronology().toString())
+                .append(" ")
+                .append(getEra())
+                .append(" ")
+                .append(yoe)
+                .append(moy < 10 ? "-0" : "-").append(moy)
+                .append(dom < 10 ? "-0" : "-").append(dom);
+        return buf.toString();
+    }
+
+}
--- a/src/share/classes/java/time/chrono/ChronoLocalDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/ChronoLocalDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -165,6 +165,7 @@
         if (temporal instanceof ChronoLocalDateTime) {
             return (ChronoLocalDateTime<?>) temporal;
         }
+        Objects.requireNonNull(temporal, "temporal");
         Chronology chrono = temporal.query(TemporalQuery.chronology());
         if (chrono == null) {
             throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass());
@@ -174,6 +175,18 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Gets the chronology of this date-time.
+     * <p>
+     * The {@code Chronology} represents the calendar system in use.
+     * The era and other fields in {@link ChronoField} are defined by the chronology.
+     *
+     * @return the chronology, not null
+     */
+    default Chronology getChronology() {
+        return toLocalDate().getChronology();
+    }
+
+    /**
      * Gets the local date part of this date-time.
      * <p>
      * This returns a local date with the same year, month and day
@@ -250,7 +263,7 @@
      */
     @Override
     default ChronoLocalDateTime<D> with(TemporalAdjuster adjuster) {
-        return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster));
+        return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.with(adjuster));
     }
 
     /**
@@ -268,7 +281,7 @@
      */
     @Override
     default ChronoLocalDateTime<D> plus(TemporalAmount amount) {
-        return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount));
+        return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.plus(amount));
     }
 
     /**
@@ -286,7 +299,7 @@
      */
     @Override
     default ChronoLocalDateTime<D> minus(TemporalAmount amount) {
-        return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount));
+        return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amount));
     }
 
     /**
@@ -296,7 +309,7 @@
      */
     @Override
     default ChronoLocalDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
-        return ChronoLocalDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit));
+        return ChronoLocalDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit));
     }
 
     //-----------------------------------------------------------------------
@@ -326,7 +339,7 @@
         } else if (query == TemporalQuery.localTime()) {
             return (R) toLocalTime();
         } else if (query == TemporalQuery.chronology()) {
-            return (R) toLocalDate().getChronology();
+            return (R) getChronology();
         } else if (query == TemporalQuery.precision()) {
             return (R) NANOS;
         }
@@ -488,7 +501,7 @@
         if (cmp == 0) {
             cmp = toLocalTime().compareTo(other.toLocalTime());
             if (cmp == 0) {
-                cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology());
+                cmp = getChronology().compareTo(other.getChronology());
             }
         }
         return cmp;
--- a/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java	Tue Oct 08 14:57:32 2013 -0700
@@ -69,7 +69,6 @@
 import java.io.ObjectOutput;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.DateTimeException;
 import java.time.LocalTime;
 import java.time.ZoneId;
 import java.time.temporal.ChronoField;
@@ -187,9 +186,9 @@
     static <R extends ChronoLocalDate> ChronoLocalDateTimeImpl<R> ensureValid(Chronology chrono, Temporal temporal) {
         @SuppressWarnings("unchecked")
         ChronoLocalDateTimeImpl<R> other = (ChronoLocalDateTimeImpl<R>) temporal;
-        if (chrono.equals(other.toLocalDate().getChronology()) == false) {
+        if (chrono.equals(other.getChronology()) == false) {
             throw new ClassCastException("Chronology mismatch, required: " + chrono.getId()
-                    + ", actual: " + other.toLocalDate().getChronology().getId());
+                    + ", actual: " + other.getChronology().getId());
         }
         return other;
     }
@@ -220,7 +219,7 @@
             return this;
         }
         // Validate that the new Temporal is a ChronoLocalDate (and not something else)
-        D cd = ChronoDateImpl.ensureValid(date.getChronology(), newDate);
+        D cd = ChronoLocalDateImpl.ensureValid(date.getChronology(), newDate);
         return new ChronoLocalDateTimeImpl<>(cd, newTime);
     }
 
@@ -369,15 +368,10 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public long until(Temporal endDateTime, TemporalUnit unit) {
-        if (endDateTime instanceof ChronoLocalDateTime == false) {
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        Objects.requireNonNull(endExclusive, "endExclusive");
         @SuppressWarnings("unchecked")
-        ChronoLocalDateTime<D> end = (ChronoLocalDateTime<D>) endDateTime;
-        if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) {
-            throw new DateTimeException("Unable to calculate amount as objects have different chronologies");
-        }
+        ChronoLocalDateTime<D> end = (ChronoLocalDateTime<D>) getChronology().localDateTime(endExclusive);
         if (unit instanceof ChronoUnit) {
             if (unit.isTimeBased()) {
                 long amount = end.getLong(EPOCH_DAY) - date.getLong(EPOCH_DAY);
@@ -398,7 +392,8 @@
             }
             return date.until(endDate, unit);
         }
-        return unit.between(this, endDateTime);
+        Objects.requireNonNull(unit, "unit");
+        return unit.between(this, end);
     }
 
     //-----------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/time/chrono/ChronoPeriod.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,365 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 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 java.time.chrono;
+
+import java.time.DateTimeException;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A date-based amount of time, such as '3 years, 4 months and 5 days' in an
+ * arbitrary chronology, intended for advanced globalization use cases.
+ * <p>
+ * This interface models a date-based amount of time in a calendar system.
+ * While most calendar systems use years, months and days, some do not.
+ * Therefore, this interface operates solely in terms of a set of supported
+ * units that are defined by the {@code Chronology}.
+ * The set of supported units is fixed for a given chronology.
+ * The amount of a supported unit may be set to zero.
+ * <p>
+ * The period is modeled as a directed amount of time, meaning that individual
+ * parts of the period may be negative.
+ *
+ * @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.
+ *
+ * @since 1.8
+ */
+public interface ChronoPeriod
+        extends TemporalAmount {
+
+    /**
+     * Obtains a {@code ChronoPeriod} consisting of amount of time between two dates.
+     * <p>
+     * The start date is included, but the end date is not.
+     * The period is calculated using {@link ChronoLocalDate#until(ChronoLocalDate)}.
+     * As such, the calculation is chronology specific.
+     * <p>
+     * The chronology of the first date is used.
+     * The chronology of the second date is ignored, with the date being converted
+     * to the target chronology system before the calculation starts.
+     * <p>
+     * The result of this method can be a negative period if the end is before the start.
+     * In most cases, the positive/negative sign will be the same in each of the supported fields.
+     *
+     * @param startDateInclusive  the start date, inclusive, specifying the chronology of the calculation, not null
+     * @param endDateExclusive  the end date, exclusive, in any chronology, not null
+     * @return the period between this date and the end date, not null
+     * @see ChronoLocalDate#until(ChronoLocalDate)
+     */
+    public static ChronoPeriod between(ChronoLocalDate startDateInclusive, ChronoLocalDate endDateExclusive) {
+        Objects.requireNonNull(startDateInclusive, "startDateInclusive");
+        Objects.requireNonNull(endDateExclusive, "endDateExclusive");
+        return startDateInclusive.until(endDateExclusive);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Gets the value of the requested unit.
+     * <p>
+     * The supported units are chronology specific.
+     * They will typically be {@link ChronoUnit#YEARS YEARS},
+     * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
+     * Requesting an unsupported unit will throw an exception.
+     *
+     * @param unit the {@code TemporalUnit} for which to return the value
+     * @return the long value of the unit
+     * @throws DateTimeException if the unit is not supported
+     * @throws UnsupportedTemporalTypeException if the unit is not supported
+     */
+    @Override
+    long get(TemporalUnit unit);
+
+    /**
+     * Gets the set of units supported by this period.
+     * <p>
+     * The supported units are chronology specific.
+     * They will typically be {@link ChronoUnit#YEARS YEARS},
+     * {@link ChronoUnit#MONTHS MONTHS} and {@link ChronoUnit#DAYS DAYS}.
+     * They are returned in order from largest to smallest.
+     * <p>
+     * This set can be used in conjunction with {@link #get(TemporalUnit)}
+     * to access the entire state of the period.
+     *
+     * @return a list containing the supported units, not null
+     */
+    @Override
+    List<TemporalUnit> getUnits();
+
+    /**
+     * Gets the chronology that defines the meaning of the supported units.
+     * <p>
+     * The period is defined by the chronology.
+     * It controls the supported units and restricts addition/subtraction
+     * to {@code ChronoLocalDate} instances of the same chronology.
+     *
+     * @return the chronology defining the period, not null
+     */
+    Chronology getChronology();
+
+    //-----------------------------------------------------------------------
+    /**
+     * Checks if all the supported units of this period are zero.
+     *
+     * @return true if this period is zero-length
+     */
+    default boolean isZero() {
+        for (TemporalUnit unit : getUnits()) {
+            if (get(unit) != 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Checks if any of the supported units of this period are negative.
+     *
+     * @return true if any unit of this period is negative
+     */
+    default boolean isNegative() {
+        for (TemporalUnit unit : getUnits()) {
+            if (get(unit) < 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a copy of this period with the specified period added.
+     * <p>
+     * If the specified amount is a {@code ChronoPeriod} then it must have
+     * the same chronology as this period. Implementations may choose to
+     * accept or reject other {@code TemporalAmount} implementations.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToAdd  the period to add, not null
+     * @return a {@code ChronoPeriod} based on this period with the requested period added, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    ChronoPeriod plus(TemporalAmount amountToAdd);
+
+    /**
+     * Returns a copy of this period with the specified period subtracted.
+     * <p>
+     * If the specified amount is a {@code ChronoPeriod} then it must have
+     * the same chronology as this period. Implementations may choose to
+     * accept or reject other {@code TemporalAmount} implementations.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param amountToSubtract  the period to subtract, not null
+     * @return a {@code ChronoPeriod} based on this period with the requested period subtracted, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    ChronoPeriod minus(TemporalAmount amountToSubtract);
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a new instance with each amount in this period in this period
+     * multiplied by the specified scalar.
+     * <p>
+     * This returns a period with each supported unit individually multiplied.
+     * For example, a period of "2 years, -3 months and 4 days" multiplied by
+     * 3 will return "6 years, -9 months and 12 days".
+     * No normalization is performed.
+     *
+     * @param scalar  the scalar to multiply by, not null
+     * @return a {@code ChronoPeriod} based on this period with the amounts multiplied
+     *  by the scalar, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    ChronoPeriod multipliedBy(int scalar);
+
+    /**
+     * Returns a new instance with each amount in this period negated.
+     * <p>
+     * This returns a period with each supported unit individually negated.
+     * For example, a period of "2 years, -3 months and 4 days" will be
+     * negated to "-2 years, 3 months and -4 days".
+     * No normalization is performed.
+     *
+     * @return a {@code ChronoPeriod} based on this period with the amounts negated, not null
+     * @throws ArithmeticException if numeric overflow occurs, which only happens if
+     *  one of the units has the value {@code Long.MIN_VALUE}
+     */
+    default ChronoPeriod negated() {
+        return multipliedBy(-1);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a copy of this period with the amounts of each unit normalized.
+     * <p>
+     * The process of normalization is specific to each calendar system.
+     * For example, in the ISO calendar system, the years and months are
+     * normalized but the days are not, such that "15 months" would be
+     * normalized to "1 year and 3 months".
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return a {@code ChronoPeriod} based on this period with the amounts of each
+     *  unit normalized, not null
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    ChronoPeriod normalized();
+
+    //-------------------------------------------------------------------------
+    /**
+     * Adds this period to the specified temporal object.
+     * <p>
+     * This returns a temporal object of the same observable type as the input
+     * with this period added.
+     * <p>
+     * In most cases, it is clearer to reverse the calling pattern by using
+     * {@link Temporal#plus(TemporalAmount)}.
+     * <pre>
+     *   // these two lines are equivalent, but the second approach is recommended
+     *   dateTime = thisPeriod.addTo(dateTime);
+     *   dateTime = dateTime.plus(thisPeriod);
+     * </pre>
+     * <p>
+     * The specified temporal must have the same chronology as this period.
+     * This returns a temporal with the non-zero supported units added.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param temporal  the temporal object to adjust, not null
+     * @return an object of the same type with the adjustment made, not null
+     * @throws DateTimeException if unable to add
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    @Override
+    Temporal addTo(Temporal temporal);
+
+    /**
+     * Subtracts this period from the specified temporal object.
+     * <p>
+     * This returns a temporal object of the same observable type as the input
+     * with this period subtracted.
+     * <p>
+     * In most cases, it is clearer to reverse the calling pattern by using
+     * {@link Temporal#minus(TemporalAmount)}.
+     * <pre>
+     *   // these two lines are equivalent, but the second approach is recommended
+     *   dateTime = thisPeriod.subtractFrom(dateTime);
+     *   dateTime = dateTime.minus(thisPeriod);
+     * </pre>
+     * <p>
+     * The specified temporal must have the same chronology as this period.
+     * This returns a temporal with the non-zero supported units subtracted.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param temporal  the temporal object to adjust, not null
+     * @return an object of the same type with the adjustment made, not null
+     * @throws DateTimeException if unable to subtract
+     * @throws ArithmeticException if numeric overflow occurs
+     */
+    @Override
+    Temporal subtractFrom(Temporal temporal);
+
+    //-----------------------------------------------------------------------
+    /**
+     * Checks if this period is equal to another period, including the chronology.
+     * <p>
+     * Compares this period with another ensuring that the type, each amount and
+     * the chronology are the same.
+     * Note that this means that a period of "15 Months" is not equal to a period
+     * of "1 Year and 3 Months".
+     *
+     * @param obj  the object to check, null returns false
+     * @return true if this is equal to the other period
+     */
+    @Override
+    boolean equals(Object obj);
+
+    /**
+     * A hash code for this period.
+     *
+     * @return a suitable hash code
+     */
+    @Override
+    int hashCode();
+
+    //-----------------------------------------------------------------------
+    /**
+     * Outputs this period as a {@code String}.
+     * <p>
+     * The output will include the period amounts and chronology.
+     *
+     * @return a string representation of this period, not null
+     */
+    @Override
+    String toString();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/time/chrono/ChronoPeriodImpl.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,399 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 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 java.time.chrono;
+
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.MONTHS;
+import static java.time.temporal.ChronoUnit.YEARS;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.time.DateTimeException;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalAmount;
+import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+import java.time.temporal.ValueRange;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A period expressed in terms of a standard year-month-day calendar system.
+ * <p>
+ * This class is used by applications seeking to handle dates in non-ISO calendar systems.
+ * For example, the Japanese, Minguo, Thai Buddhist and others.
+ *
+ * @implSpec
+ * This class is immutable nad thread-safe.
+ *
+ * @since 1.8
+ */
+final class ChronoPeriodImpl
+        implements ChronoPeriod, Serializable {
+    // this class is only used by JDK chronology implementations and makes assumptions based on that fact
+
+    /**
+     * Serialization version.
+     */
+    private static final long serialVersionUID = 57387258289L;
+
+    /**
+     * The set of supported units.
+     */
+    private final static List<TemporalUnit> SUPPORTED_UNITS =
+            Collections.unmodifiableList(Arrays.<TemporalUnit>asList(YEARS, MONTHS, DAYS));
+
+    /**
+     * The chronology.
+     */
+    private final Chronology chrono;
+    /**
+     * The number of years.
+     */
+    final int years;
+    /**
+     * The number of months.
+     */
+    final int months;
+    /**
+     * The number of days.
+     */
+    final int days;
+
+    /**
+     * Creates an instance.
+     */
+    ChronoPeriodImpl(Chronology chrono, int years, int months, int days) {
+        Objects.requireNonNull(chrono, "chrono");
+        this.chrono = chrono;
+        this.years = years;
+        this.months = months;
+        this.days = days;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public long get(TemporalUnit unit) {
+        if (unit == ChronoUnit.YEARS) {
+            return years;
+        } else if (unit == ChronoUnit.MONTHS) {
+            return months;
+        } else if (unit == ChronoUnit.DAYS) {
+            return days;
+        } else {
+            throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);
+        }
+    }
+
+    @Override
+    public List<TemporalUnit> getUnits() {
+        return ChronoPeriodImpl.SUPPORTED_UNITS;
+    }
+
+    @Override
+    public Chronology getChronology() {
+        return chrono;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public boolean isZero() {
+        return years == 0 && months == 0 && days == 0;
+    }
+
+    @Override
+    public boolean isNegative() {
+        return years < 0 || months < 0 || days < 0;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public ChronoPeriod plus(TemporalAmount amountToAdd) {
+        ChronoPeriodImpl amount = validateAmount(amountToAdd);
+        return new ChronoPeriodImpl(
+                chrono,
+                Math.addExact(years, amount.years),
+                Math.addExact(months, amount.months),
+                Math.addExact(days, amount.days));
+    }
+
+    @Override
+    public ChronoPeriod minus(TemporalAmount amountToSubtract) {
+        ChronoPeriodImpl amount = validateAmount(amountToSubtract);
+        return new ChronoPeriodImpl(
+                chrono,
+                Math.subtractExact(years, amount.years),
+                Math.subtractExact(months, amount.months),
+                Math.subtractExact(days, amount.days));
+    }
+
+    /**
+     * Obtains an instance of {@code ChronoPeriodImpl} from a temporal amount.
+     *
+     * @param amount  the temporal amount to convert, not null
+     * @return the period, not null
+     */
+    private ChronoPeriodImpl validateAmount(TemporalAmount amount) {
+        Objects.requireNonNull(amount, "amount");
+        if (amount instanceof ChronoPeriodImpl == false) {
+            throw new DateTimeException("Unable to obtain ChronoPeriod from TemporalAmount: " + amount.getClass());
+        }
+        ChronoPeriodImpl period = (ChronoPeriodImpl) amount;
+        if (chrono.equals(period.getChronology()) == false) {
+            throw new ClassCastException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + period.getChronology().getId());
+        }
+        return period;
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public ChronoPeriod multipliedBy(int scalar) {
+        if (this.isZero() || scalar == 1) {
+            return this;
+        }
+        return new ChronoPeriodImpl(
+                chrono,
+                Math.multiplyExact(years, scalar),
+                Math.multiplyExact(months, scalar),
+                Math.multiplyExact(days, scalar));
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public ChronoPeriod normalized() {
+        long monthRange = monthRange();
+        if (monthRange > 0) {
+            long totalMonths = years * monthRange + months;
+            long splitYears = totalMonths / monthRange;
+            int splitMonths = (int) (totalMonths % monthRange);  // no overflow
+            if (splitYears == years && splitMonths == months) {
+                return this;
+            }
+            return new ChronoPeriodImpl(chrono, Math.toIntExact(splitYears), splitMonths, days);
+
+        }
+        return this;
+    }
+
+    /**
+     * Calculates the range of months.
+     *
+     * @return the month range, -1 if not fixed range
+     */
+    private long monthRange() {
+        ValueRange startRange = chrono.range(MONTH_OF_YEAR);
+        if (startRange.isFixed() && startRange.isIntValue()) {
+            return startRange.getMaximum() - startRange.getMinimum() + 1;
+        }
+        return -1;
+    }
+
+    //-------------------------------------------------------------------------
+    @Override
+    public Temporal addTo(Temporal temporal) {
+        validateChrono(temporal);
+        if (months == 0) {
+            if (years != 0) {
+                temporal = temporal.plus(years, YEARS);
+            }
+        } else {
+            long monthRange = monthRange();
+            if (monthRange > 0) {
+                temporal = temporal.plus(years * monthRange + months, MONTHS);
+            } else {
+                if (years != 0) {
+                    temporal = temporal.plus(years, YEARS);
+                }
+                temporal = temporal.plus(months, MONTHS);
+            }
+        }
+        if (days != 0) {
+            temporal = temporal.plus(days, DAYS);
+        }
+        return temporal;
+    }
+
+
+
+    @Override
+    public Temporal subtractFrom(Temporal temporal) {
+        validateChrono(temporal);
+        if (months == 0) {
+            if (years != 0) {
+                temporal = temporal.minus(years, YEARS);
+            }
+        } else {
+            long monthRange = monthRange();
+            if (monthRange > 0) {
+                temporal = temporal.minus(years * monthRange + months, MONTHS);
+            } else {
+                if (years != 0) {
+                    temporal = temporal.minus(years, YEARS);
+                }
+                temporal = temporal.minus(months, MONTHS);
+            }
+        }
+        if (days != 0) {
+            temporal = temporal.minus(days, DAYS);
+        }
+        return temporal;
+    }
+
+    /**
+     * Validates that the temporal has the correct chronology.
+     */
+    private void validateChrono(TemporalAccessor temporal) {
+        Objects.requireNonNull(temporal, "temporal");
+        Chronology temporalChrono = temporal.query(TemporalQuery.chronology());
+        if (temporalChrono != null && chrono.equals(temporalChrono) == false) {
+            throw new DateTimeException("Chronology mismatch, expected: " + chrono.getId() + ", actual: " + temporalChrono.getId());
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ChronoPeriodImpl) {
+            ChronoPeriodImpl other = (ChronoPeriodImpl) obj;
+            return years == other.years && months == other.months &&
+                    days == other.days && chrono.equals(other.chrono);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return (years + Integer.rotateLeft(months, 8) + Integer.rotateLeft(days, 16)) ^ chrono.hashCode();
+    }
+
+    //-----------------------------------------------------------------------
+    @Override
+    public String toString() {
+        if (isZero()) {
+            return getChronology().toString() + " P0D";
+        } else {
+            StringBuilder buf = new StringBuilder();
+            buf.append(getChronology().toString()).append(' ').append('P');
+            if (years != 0) {
+                buf.append(years).append('Y');
+            }
+            if (months != 0) {
+                buf.append(months).append('M');
+            }
+            if (days != 0) {
+                buf.append(days).append('D');
+            }
+            return buf.toString();
+        }
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Writes the Chronology using a
+     * <a href="../../../serialized-form.html#java.time.chrono.Ser">dedicated serialized form</a>.
+     * <pre>
+     *  out.writeByte(12);  // identifies this as a ChronoPeriodImpl
+     *  out.writeUTF(getId());  // the chronology
+     *  out.writeInt(years);
+     *  out.writeInt(months);
+     *  out.writeInt(days);
+     * </pre>
+     *
+     * @return the instance of {@code Ser}, not null
+     */
+    protected Object writeReplace() {
+        return new Ser(Ser.CHRONO_PERIOD_TYPE, this);
+    }
+
+    /**
+     * Defend against malicious streams.
+     * @return never
+     * @throws InvalidObjectException always
+     */
+    private Object readResolve() throws ObjectStreamException {
+        throw new InvalidObjectException("Deserialization via serialization delegate");
+    }
+
+    void writeExternal(DataOutput out) throws IOException {
+        out.writeUTF(chrono.getId());
+        out.writeInt(years);
+        out.writeInt(months);
+        out.writeInt(days);
+    }
+
+    static ChronoPeriodImpl readExternal(DataInput in) throws IOException {
+        Chronology chrono = Chronology.of(in.readUTF());
+        int years = in.readInt();
+        int months = in.readInt();
+        int days = in.readInt();
+        return new ChronoPeriodImpl(chrono, years, months, days);
+    }
+
+}
--- a/src/share/classes/java/time/chrono/ChronoZonedDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/ChronoZonedDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -166,6 +166,7 @@
         if (temporal instanceof ChronoZonedDateTime) {
             return (ChronoZonedDateTime<?>) temporal;
         }
+        Objects.requireNonNull(temporal, "temporal");
         Chronology chrono = temporal.query(TemporalQuery.chronology());
         if (chrono == null) {
             throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass());
@@ -246,6 +247,18 @@
     ChronoLocalDateTime<D> toLocalDateTime();
 
     /**
+     * Gets the chronology of this date-time.
+     * <p>
+     * The {@code Chronology} represents the calendar system in use.
+     * The era and other fields in {@link ChronoField} are defined by the chronology.
+     *
+     * @return the chronology, not null
+     */
+    default Chronology getChronology() {
+        return toLocalDate().getChronology();
+    }
+
+    /**
      * Gets the zone offset, such as '+01:00'.
      * <p>
      * This is the offset of the local date-time from UTC/Greenwich.
@@ -397,7 +410,7 @@
      */
     @Override
     default ChronoZonedDateTime<D> with(TemporalAdjuster adjuster) {
-        return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.with(adjuster));
+        return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.with(adjuster));
     }
 
     /**
@@ -415,7 +428,7 @@
      */
     @Override
     default ChronoZonedDateTime<D> plus(TemporalAmount amount) {
-        return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.plus(amount));
+        return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.plus(amount));
     }
 
     /**
@@ -433,7 +446,7 @@
      */
     @Override
     default ChronoZonedDateTime<D> minus(TemporalAmount amount) {
-        return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amount));
+        return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amount));
     }
 
     /**
@@ -443,7 +456,7 @@
      */
     @Override
     default ChronoZonedDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
-        return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), Temporal.super.minus(amountToSubtract, unit));
+        return ChronoZonedDateTimeImpl.ensureValid(getChronology(), Temporal.super.minus(amountToSubtract, unit));
     }
 
     //-----------------------------------------------------------------------
@@ -475,7 +488,7 @@
         } else if (query == TemporalQuery.localTime()) {
             return (R) toLocalTime();
         } else if (query == TemporalQuery.chronology()) {
-            return (R) toLocalDate().getChronology();
+            return (R) getChronology();
         } else if (query == TemporalQuery.precision()) {
             return (R) NANOS;
         }
@@ -562,7 +575,7 @@
                 if (cmp == 0) {
                     cmp = getZone().getId().compareTo(other.getZone().getId());
                     if (cmp == 0) {
-                        cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology());
+                        cmp = getChronology().compareTo(other.getChronology());
                     }
                 }
             }
--- a/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/ChronoZonedDateTimeImpl.java	Tue Oct 08 14:57:32 2013 -0700
@@ -69,7 +69,6 @@
 import java.io.ObjectOutput;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -186,7 +185,7 @@
      */
     @SuppressWarnings("unchecked")
     private ChronoZonedDateTimeImpl<D> create(Instant instant, ZoneId zone) {
-        return (ChronoZonedDateTimeImpl<D>)ofInstant(toLocalDate().getChronology(), instant, zone);
+        return (ChronoZonedDateTimeImpl<D>)ofInstant(getChronology(), instant, zone);
     }
 
     /**
@@ -201,9 +200,9 @@
     static <R extends ChronoLocalDate> ChronoZonedDateTimeImpl<R> ensureValid(Chronology chrono, Temporal temporal) {
         @SuppressWarnings("unchecked")
         ChronoZonedDateTimeImpl<R> other = (ChronoZonedDateTimeImpl<R>) temporal;
-        if (chrono.equals(other.toLocalDate().getChronology()) == false) {
+        if (chrono.equals(other.getChronology()) == false) {
             throw new ClassCastException("Chronology mismatch, required: " + chrono.getId()
-                    + ", actual: " + other.toLocalDate().getChronology().getId());
+                    + ", actual: " + other.getChronology().getId());
         }
         return other;
     }
@@ -234,7 +233,7 @@
         if (trans != null && trans.isOverlap()) {
             ZoneOffset earlierOffset = trans.getOffsetBefore();
             if (earlierOffset.equals(offset) == false) {
-                return new ChronoZonedDateTimeImpl<D>(dateTime, earlierOffset, zone);
+                return new ChronoZonedDateTimeImpl<>(dateTime, earlierOffset, zone);
             }
         }
         return this;
@@ -246,7 +245,7 @@
         if (trans != null) {
             ZoneOffset offset = trans.getOffsetAfter();
             if (offset.equals(getOffset()) == false) {
-                return new ChronoZonedDateTimeImpl<D>(dateTime, offset, zone);
+                return new ChronoZonedDateTimeImpl<>(dateTime, offset, zone);
             }
         }
         return this;
@@ -294,7 +293,7 @@
             }
             return ofBest(dateTime.with(field, newValue), zone, offset);
         }
-        return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), field.adjustInto(this, newValue));
+        return ChronoZonedDateTimeImpl.ensureValid(getChronology(), field.adjustInto(this, newValue));
     }
 
     //-----------------------------------------------------------------------
@@ -303,25 +302,21 @@
         if (unit instanceof ChronoUnit) {
             return with(dateTime.plus(amountToAdd, unit));
         }
-        return ChronoZonedDateTimeImpl.ensureValid(toLocalDate().getChronology(), unit.addTo(this, amountToAdd));   /// TODO: Generics replacement Risk!
+        return ChronoZonedDateTimeImpl.ensureValid(getChronology(), unit.addTo(this, amountToAdd));   /// TODO: Generics replacement Risk!
     }
 
     //-----------------------------------------------------------------------
     @Override
-    public long until(Temporal endDateTime, TemporalUnit unit) {
-        if (endDateTime instanceof ChronoZonedDateTime == false) {
-            throw new DateTimeException("Unable to calculate amount as objects are of two different types");
-        }
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        Objects.requireNonNull(endExclusive, "endExclusive");
         @SuppressWarnings("unchecked")
-        ChronoZonedDateTime<D> end = (ChronoZonedDateTime<D>) endDateTime;
-        if (toLocalDate().getChronology().equals(end.toLocalDate().getChronology()) == false) {
-            throw new DateTimeException("Unable to calculate amount as objects have different chronologies");
-        }
+        ChronoZonedDateTime<D> end = (ChronoZonedDateTime<D>) getChronology().zonedDateTime(endExclusive);
         if (unit instanceof ChronoUnit) {
             end = end.withZoneSameInstant(offset);
             return dateTime.until(end.toLocalDateTime(), unit);
         }
-        return unit.between(this, endDateTime);
+        Objects.requireNonNull(unit, "unit");
+        return unit.between(this, end);
     }
 
     //-----------------------------------------------------------------------
--- a/src/share/classes/java/time/chrono/Chronology.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/Chronology.java	Tue Oct 08 14:57:32 2013 -0700
@@ -91,14 +91,11 @@
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.time.Month;
-import java.time.Year;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.ResolverStyle;
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoField;
-import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalAdjuster;
 import java.time.temporal.TemporalField;
@@ -1192,6 +1189,38 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Obtains a period for this chronology based on years, months and days.
+     * <p>
+     * This returns a period tied to this chronology using the specified
+     * years, months and days.  All supplied chronologies use periods
+     * based on years, months and days, however the {@code ChronoPeriod} API
+     * allows the period to be represented using other units.
+     *
+     * @implSpec
+     * The default implementation returns an implementation class suitable
+     * for most calendar systems. It is based solely on the three units.
+     * Normalization, addition and subtraction derive the number of months
+     * in a year from the {@link #range(ChronoField)}. If the number of
+     * months within a year is fixed, then the calculation approach for
+     * addition, subtraction and normalization is slightly different.
+     * <p>
+     * If implementing an unusual calendar system that is not based on
+     * years, months and days, or where you want direct control, then
+     * the {@code ChronoPeriod} interface must be directly implemented.
+     * <p>
+     * The returned period is immutable and thread-safe.
+     *
+     * @param years  the number of years, may be negative
+     * @param months  the number of years, may be negative
+     * @param days  the number of years, may be negative
+     * @return the period in terms of this chronology, not null
+     */
+    public ChronoPeriod period(int years, int months, int days) {
+        return new ChronoPeriodImpl(this, years, months, days);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Compares this chronology to another chronology.
      * <p>
      * The comparison order first by the chronology ID string, then by any
--- a/src/share/classes/java/time/chrono/HijrahDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/HijrahDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -73,7 +73,6 @@
 import java.time.DateTimeException;
 import java.time.LocalDate;
 import java.time.LocalTime;
-import java.time.Period;
 import java.time.ZoneId;
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
@@ -109,7 +108,7 @@
  * @since 1.8
  */
 public final class HijrahDate
-        extends ChronoDateImpl<HijrahDate>
+        extends ChronoLocalDateImpl<HijrahDate>
         implements ChronoLocalDate, Serializable {
 
     /**
@@ -582,7 +581,7 @@
     }
 
     @Override
-    public Period until(ChronoLocalDate endDate) {
+    public ChronoPeriod until(ChronoLocalDate endDate) {
         // TODO: untested
         HijrahDate end = getChronology().date(endDate);
         long totalMonths = (end.prolepticYear - this.prolepticYear) * 12 + (end.monthOfYear - this.monthOfYear);  // safe
@@ -597,7 +596,7 @@
         }
         long years = totalMonths / 12;  // safe
         int months = (int) (totalMonths % 12);  // safe
-        return Period.of(Math.toIntExact(years), months, days);
+        return getChronology().period(Math.toIntExact(years), months, days);
     }
 
     //-----------------------------------------------------------------------
--- a/src/share/classes/java/time/chrono/IsoChronology.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/IsoChronology.java	Tue Oct 08 14:57:32 2013 -0700
@@ -77,6 +77,7 @@
 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.ZonedDateTime;
@@ -567,6 +568,24 @@
 
     //-----------------------------------------------------------------------
     /**
+     * Obtains a period for this chronology based on years, months and days.
+     * <p>
+     * This returns a period tied to the ISO chronology using the specified
+     * years, months and days. See {@link Period} for further details.
+     *
+     * @param years  the number of years, may be negative
+     * @param months  the number of years, may be negative
+     * @param days  the number of years, may be negative
+     * @return the period in terms of this chronology, not null
+     * @return the ISO period, not null
+     */
+    @Override  // override with covariant return type
+    public Period period(int years, int months, int days) {
+        return Period.of(years, months, days);
+    }
+
+    //-----------------------------------------------------------------------
+    /**
      * Writes the Chronology using a
      * <a href="../../../serialized-form.html#java.time.chrono.Ser">dedicated serialized form</a>.
      * @serialData
--- a/src/share/classes/java/time/chrono/JapaneseDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/JapaneseDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -61,10 +61,8 @@
 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
 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 java.io.DataInput;
 import java.io.DataOutput;
@@ -76,7 +74,6 @@
 import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.Period;
-import java.time.Year;
 import java.time.ZoneId;
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
@@ -119,7 +116,7 @@
  * @since 1.8
  */
 public final class JapaneseDate
-        extends ChronoDateImpl<JapaneseDate>
+        extends ChronoLocalDateImpl<JapaneseDate>
         implements ChronoLocalDate, Serializable {
 
     /**
@@ -662,8 +659,9 @@
     }
 
     @Override
-    public Period until(ChronoLocalDate endDate) {
-        return isoDate.until(endDate);
+    public ChronoPeriod until(ChronoLocalDate endDate) {
+        Period period = isoDate.until(endDate);
+        return getChronology().period(period.getYears(), period.getMonths(), period.getDays());
     }
 
     @Override  // override for performance
--- a/src/share/classes/java/time/chrono/MinguoDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/MinguoDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -96,7 +96,7 @@
  * @since 1.8
  */
 public final class MinguoDate
-        extends ChronoDateImpl<MinguoDate>
+        extends ChronoLocalDateImpl<MinguoDate>
         implements ChronoLocalDate, Serializable {
 
     /**
@@ -421,8 +421,9 @@
     }
 
     @Override
-    public Period until(ChronoLocalDate endDate) {
-        return isoDate.until(endDate);
+    public ChronoPeriod until(ChronoLocalDate endDate) {
+        Period period = isoDate.until(endDate);
+        return getChronology().period(period.getYears(), period.getMonths(), period.getDays());
     }
 
     @Override  // override for performance
--- a/src/share/classes/java/time/chrono/Ser.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/Ser.java	Tue Oct 08 14:57:32 2013 -0700
@@ -104,6 +104,7 @@
     static final byte HIJRAH_DATE_TYPE = 6;
     static final byte MINGUO_DATE_TYPE = 7;
     static final byte THAIBUDDHIST_DATE_TYPE = 8;
+    static final byte CHRONO_PERIOD_TYPE = 9;
 
     /** The type being serialized. */
     private byte type;
@@ -183,6 +184,9 @@
             case THAIBUDDHIST_DATE_TYPE:
                 ((ThaiBuddhistDate) object).writeExternal(out);
                 break;
+            case CHRONO_PERIOD_TYPE:
+                ((ChronoPeriodImpl) object).writeExternal(out);
+                break;
             default:
                 throw new InvalidClassException("Unknown serialized type");
         }
@@ -235,6 +239,7 @@
             case HIJRAH_DATE_TYPE: return HijrahDate.readExternal(in);
             case MINGUO_DATE_TYPE: return MinguoDate.readExternal(in);
             case THAIBUDDHIST_DATE_TYPE: return ThaiBuddhistDate.readExternal(in);
+            case CHRONO_PERIOD_TYPE: return ChronoPeriodImpl.readExternal(in);
             default: throw new StreamCorruptedException("Unknown serialized type");
         }
     }
--- a/src/share/classes/java/time/chrono/ThaiBuddhistDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/chrono/ThaiBuddhistDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -96,7 +96,7 @@
  * @since 1.8
  */
 public final class ThaiBuddhistDate
-        extends ChronoDateImpl<ThaiBuddhistDate>
+        extends ChronoLocalDateImpl<ThaiBuddhistDate>
         implements ChronoLocalDate, Serializable {
 
     /**
@@ -421,8 +421,9 @@
     }
 
     @Override
-    public Period until(ChronoLocalDate endDate) {
-        return isoDate.until(endDate);
+    public ChronoPeriod until(ChronoLocalDate endDate) {
+        Period period = isoDate.until(endDate);
+        return getChronology().period(period.getYears(), period.getMonths(), period.getDays());
     }
 
     @Override  // override for performance
--- a/src/share/classes/java/time/format/Parsed.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/format/Parsed.java	Tue Oct 08 14:57:32 2013 -0700
@@ -83,6 +83,8 @@
 import java.time.Period;
 import java.time.ZoneId;
 import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
 import java.time.chrono.Chronology;
 import java.time.temporal.ChronoField;
 import java.time.temporal.TemporalAccessor;
@@ -260,11 +262,34 @@
             while (changedCount < 50) {
                 for (Map.Entry<TemporalField, Long> entry : fieldValues.entrySet()) {
                     TemporalField targetField = entry.getKey();
-                    ChronoLocalDate resolvedDate = targetField.resolve(fieldValues, chrono, zone, resolverStyle);
-                    if (resolvedDate != null) {
-                        updateCheckConflict(resolvedDate);
-                        changedCount++;
-                        continue outer;  // have to restart to avoid concurrent modification
+                    TemporalAccessor resolvedObject = targetField.resolve(fieldValues, chrono, zone, resolverStyle);
+                    if (resolvedObject != null) {
+                        if (resolvedObject instanceof ChronoZonedDateTime) {
+                            ChronoZonedDateTime czdt = (ChronoZonedDateTime) resolvedObject;
+                            if (zone.equals(czdt.getZone()) == false) {
+                                throw new DateTimeException("ChronoZonedDateTime must use the effective parsed zone: " + zone);
+                            }
+                            resolvedObject = czdt.toLocalDateTime();
+                        }
+                        if (resolvedObject instanceof ChronoLocalDateTime) {
+                            ChronoLocalDateTime cldt = (ChronoLocalDateTime) resolvedObject;
+                            updateCheckConflict(cldt.toLocalTime(), Period.ZERO);
+                            updateCheckConflict(cldt.toLocalDate());
+                            changedCount++;
+                            continue outer;  // have to restart to avoid concurrent modification
+                        }
+                        if (resolvedObject instanceof ChronoLocalDate) {
+                            updateCheckConflict((ChronoLocalDate) resolvedObject);
+                            changedCount++;
+                            continue outer;  // have to restart to avoid concurrent modification
+                        }
+                        if (resolvedObject instanceof LocalTime) {
+                            updateCheckConflict((LocalTime) resolvedObject, Period.ZERO);
+                            changedCount++;
+                            continue outer;  // have to restart to avoid concurrent modification
+                        }
+                        throw new DateTimeException("Method resolveFields() can only return ChronoZonedDateTime," +
+                                "ChronoLocalDateTime, ChronoLocalDate or LocalTime");
                     } else if (fieldValues.containsKey(targetField) == false) {
                         changedCount++;
                         continue outer;  // have to restart to avoid concurrent modification
@@ -302,7 +327,10 @@
             if (cld != null && date.equals(cld) == false) {
                 throw new DateTimeException("Conflict found: Fields resolved to two different dates: " + date + " " + cld);
             }
-        } else {
+        } else if (cld != null) {
+            if (chrono.equals(cld.getChronology()) == false) {
+                throw new DateTimeException("ChronoLocalDate must use the effective parsed chronology: " + chrono);
+            }
             date = cld;
         }
     }
--- a/src/share/classes/java/time/temporal/ChronoUnit.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/temporal/ChronoUnit.java	Tue Oct 08 14:57:32 2013 -0700
@@ -268,8 +268,8 @@
 
     //-----------------------------------------------------------------------
     @Override
-    public long between(Temporal temporal1, Temporal temporal2) {
-        return temporal1.until(temporal2, this);
+    public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) {
+        return temporal1Inclusive.until(temporal2Exclusive, this);
     }
 
     //-----------------------------------------------------------------------
--- a/src/share/classes/java/time/temporal/IsoFields.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/temporal/IsoFields.java	Tue Oct 08 14:57:32 2013 -0700
@@ -684,13 +684,16 @@
         }
 
         @Override
-        public long between(Temporal temporal1, Temporal temporal2) {
+        public long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive) {
+            if (temporal1Inclusive.getClass() != temporal2Exclusive.getClass()) {
+                return temporal1Inclusive.until(temporal2Exclusive, this);
+            }
             switch(this) {
                 case WEEK_BASED_YEARS:
-                    return Math.subtractExact(temporal2.getLong(WEEK_BASED_YEAR),
-                            temporal1.getLong(WEEK_BASED_YEAR));
+                    return Math.subtractExact(temporal2Exclusive.getLong(WEEK_BASED_YEAR),
+                            temporal1Inclusive.getLong(WEEK_BASED_YEAR));
                 case QUARTER_YEARS:
-                    return temporal1.until(temporal2, MONTHS) / 3;
+                    return temporal1Inclusive.until(temporal2Exclusive, MONTHS) / 3;
                 default:
                     throw new IllegalStateException("Unreachable");
             }
--- a/src/share/classes/java/time/temporal/Temporal.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/temporal/Temporal.java	Tue Oct 08 14:57:32 2013 -0700
@@ -170,7 +170,8 @@
      * </pre>
      *
      * @implSpec
-     * Implementations must not alter either this object.
+     * <p>
+     * Implementations must not alter either this object or the specified temporal object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      * <p>
@@ -209,7 +210,7 @@
      * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
      * passing {@code this} as the first argument.
      * <p>
-     * Implementations must not alter either this object or the specified temporal object.
+     * Implementations must not alter this object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      *
@@ -232,16 +233,17 @@
      * <p>
      * Some example code indicating how and why this method is used:
      * <pre>
-     *  date = date.plus(period);                      // add a Period instance
-     *  date = date.plus(duration);                    // add a Duration instance
-     *  date = date.plus(workingDays(6));              // example user-written workingDays method
+     *  date = date.plus(period);                // add a Period instance
+     *  date = date.plus(duration);              // add a Duration instance
+     *  date = date.plus(workingDays(6));        // example user-written workingDays method
      * </pre>
      * <p>
      * Note that calling {@code plus} followed by {@code minus} is not guaranteed to
      * return the same date-time.
      *
      * @implSpec
-     * Implementations must not alter either this object.
+     * <p>
+     * Implementations must not alter either this object or the specified temporal object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      * <p>
@@ -280,7 +282,7 @@
      * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
      * passing {@code this} as the first argument.
      * <p>
-     * Implementations must not alter either this object or the specified temporal object.
+     * Implementations must not alter this object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      *
@@ -303,16 +305,17 @@
      * <p>
      * Some example code indicating how and why this method is used:
      * <pre>
-     *  date = date.minus(period);                      // subtract a Period instance
-     *  date = date.minus(duration);                    // subtract a Duration instance
-     *  date = date.minus(workingDays(6));              // example user-written workingDays method
+     *  date = date.minus(period);               // subtract a Period instance
+     *  date = date.minus(duration);             // subtract a Duration instance
+     *  date = date.minus(workingDays(6));       // example user-written workingDays method
      * </pre>
      * <p>
      * Note that calling {@code plus} followed by {@code minus} is not guaranteed to
      * return the same date-time.
      *
      * @implSpec
-     * Implementations must not alter either this object.
+     * <p>
+     * Implementations must not alter either this object or the specified temporal object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      * <p>
@@ -345,7 +348,7 @@
      * @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.
+     * Implementations must not alter this object.
      * Instead, an adjusted copy of the original must be returned.
      * This provides equivalent, safe behavior for immutable and mutable implementations.
      * <p>
@@ -371,8 +374,9 @@
      * Calculates the amount of time until another temporal in terms of the specified unit.
      * <p>
      * This calculates the amount of time between two temporal objects
-     * of the same type in terms of a single {@code TemporalUnit}.
+     * in terms of a single {@code TemporalUnit}.
      * The start and end points are {@code this} and the specified temporal.
+     * The end point is converted to be of the same type as the start point if different.
      * The result will be negative if the end is before the start.
      * For example, the period in hours between two temporal objects can be
      * calculated using {@code startTime.until(endTime, HOURS)}.
@@ -409,31 +413,36 @@
      * <p>
      * If the unit is not a {@code ChronoUnit}, then the result of this method
      * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
-     * passing {@code this} as the first argument and the input temporal as
+     * passing {@code this} as the first argument and the converted input temporal as
      * the second argument.
      * <p>
-     * In summary, implementations must behave in a manner equivalent to this code:
+     * In summary, implementations must behave in a manner equivalent to this pseudo-code:
      * <pre>
-     *  // check input temporal is the same type as this class
+     *  // convert the end temporal to the same type as this class
      *  if (unit instanceof ChronoUnit) {
      *    // if unit is supported, then calculate and return result
      *    // else throw UnsupportedTemporalTypeException for unsupported units
      *  }
-     *  return unit.between(this, endTemporal);
+     *  return unit.between(this, convertedEndTemporal);
      * </pre>
      * <p>
+     * Note that the unit's {@code between} method must only be invoked if the
+     * two temporal objects have exactly the same type evaluated by {@code getClass()}.
+     * <p>
      * Implementations must ensure that no observable state is altered when this
      * read-only method is invoked.
      *
-     * @param endTemporal  the end temporal, of the same type as this object, not null
+     * @param endExclusive  the end temporal, exclusive, converted to be of the
+     *  same type as this object, not null
      * @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 DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to the same type as this temporal
      * @throws UnsupportedTemporalTypeException if the unit is not supported
      * @throws ArithmeticException if numeric overflow occurs
      */
-    long until(Temporal endTemporal, TemporalUnit unit);
+    long until(Temporal endExclusive, TemporalUnit unit);
 
 }
--- a/src/share/classes/java/time/temporal/TemporalField.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/temporal/TemporalField.java	Tue Oct 08 14:57:32 2013 -0700
@@ -63,7 +63,6 @@
 
 import java.time.DateTimeException;
 import java.time.ZoneId;
-import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.Chronology;
 import java.time.format.ResolverStyle;
 import java.util.Locale;
@@ -350,6 +349,10 @@
      * be acceptable for the date fields to be resolved into other {@code ChronoField}
      * instances that can produce a date, such as {@code EPOCH_DAY}.
      * <p>
+     * Not all {@code TemporalAccessor} implementations are accepted as return values.
+     * Implementations must accept {@code ChronoLocalDate}, {@code ChronoLocalDateTime},
+     * {@code ChronoZonedDateTime} and {@code LocalTime}.
+     * <p>
      * The zone is not normally required for resolution, but is provided for completeness.
      * <p>
      * The default implementation must return null.
@@ -358,13 +361,13 @@
      * @param chronology  the effective chronology, not null
      * @param zone  the effective zone, not null
      * @param resolverStyle  the requested type of resolve, not null
-     * @return the resolved date; null if resolving only changed the map,
-     *  or no resolve occurred
+     * @return the resolved temporal object; null if resolving only
+     *  changed the map, or no resolve occurred
      * @throws ArithmeticException if numeric overflow occurs
      * @throws DateTimeException if resolving results in an error. This must not be thrown
      *  by querying a field on the temporal without first checking if it is supported
      */
-    default ChronoLocalDate resolve(
+    default TemporalAccessor resolve(
             Map<TemporalField, Long> fieldValues, Chronology chronology,
             ZoneId zone, ResolverStyle resolverStyle) {
         return null;
--- a/src/share/classes/java/time/temporal/TemporalUnit.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/temporal/TemporalUnit.java	Tue Oct 08 14:57:32 2013 -0700
@@ -231,7 +231,9 @@
      * Calculates the amount of time between two temporal objects.
      * <p>
      * 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.
+     * points are supplied as temporal objects and must be of compatible types.
+     * The implementation will convert the second type to be an instance of the
+     * first type before the calculating the amount.
      * The result will be negative if the end is before the start.
      * For example, the amount in hours between two temporal objects can be
      * calculated using {@code HOURS.between(startTime, endTime)}.
@@ -264,15 +266,22 @@
      * If the unit is not supported an {@code UnsupportedTemporalTypeException} must be thrown.
      * Implementations must not alter the specified temporal objects.
      *
-     * @param temporal1  the base temporal object, not null
-     * @param temporal2  the other temporal object, not null
-     * @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 amount cannot be calculated
+     * @implSpec
+     * Implementations must begin by checking to if the two temporals have the
+     * same type using {@code getClass()}. If they do not, then the result must be
+     * obtained by calling {@code temporal1Inclusive.until(temporal2Exclusive, this)}.
+     *
+     * @param temporal1Inclusive  the base temporal object, not null
+     * @param temporal2Exclusive  the other temporal object, exclusive, not null
+     * @return the amount of time between temporal1Inclusive and temporal2Exclusive
+     *  in terms of this unit; positive if temporal2Exclusive is later than
+     *  temporal1Inclusive, negative if earlier
+     * @throws DateTimeException if the amount cannot be calculated, or the end
+     *  temporal cannot be converted to the same type as the start temporal
      * @throws UnsupportedTemporalTypeException if the unit is not supported by the temporal
      * @throws ArithmeticException if numeric overflow occurs
      */
-    long between(Temporal temporal1, Temporal temporal2);
+    long between(Temporal temporal1Inclusive, Temporal temporal2Exclusive);
 
     //-----------------------------------------------------------------------
     /**
--- a/src/share/classes/java/time/temporal/ValueRange.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/time/temporal/ValueRange.java	Tue Oct 08 14:57:32 2013 -0700
@@ -61,6 +61,7 @@
  */
 package java.time.temporal;
 
+import java.io.InvalidObjectException;
 import java.io.Serializable;
 import java.time.DateTimeException;
 
@@ -337,6 +338,21 @@
         }
     }
 
+    /**
+     * Return the ValueRange for the serialized values.
+     * The values are validated according to the constraints of the {@link #of}
+     * factory method.
+     * @return the ValueRange for the serialized fields
+     * @throws InvalidObjectException if the serialized object has invalid values
+     */
+    private Object readResolve() throws InvalidObjectException {
+        try {
+            return of(minSmallest, minLargest, maxSmallest, maxLargest);
+        } catch (IllegalArgumentException iae) {
+            throw new InvalidObjectException("Invalid serialized ValueRange: " + iae.getMessage());
+        }
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Checks if this range is equal to another range.
--- a/src/share/classes/java/util/Arrays.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/Arrays.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1583,6 +1583,7 @@
      * @since 1.8
      */
     public static <T> void parallelPrefix(T[] array, BinaryOperator<T> op) {
+        Objects.requireNonNull(op);
         if (array.length > 0)
             new ArrayPrefixHelpers.CumulateTask<>
                     (null, op, array, 0, array.length).invoke();
@@ -1606,6 +1607,7 @@
      */
     public static <T> void parallelPrefix(T[] array, int fromIndex,
                                           int toIndex, BinaryOperator<T> op) {
+        Objects.requireNonNull(op);
         rangeCheck(array.length, fromIndex, toIndex);
         if (fromIndex < toIndex)
             new ArrayPrefixHelpers.CumulateTask<>
@@ -1627,6 +1629,7 @@
      * @since 1.8
      */
     public static void parallelPrefix(long[] array, LongBinaryOperator op) {
+        Objects.requireNonNull(op);
         if (array.length > 0)
             new ArrayPrefixHelpers.LongCumulateTask
                     (null, op, array, 0, array.length).invoke();
@@ -1649,6 +1652,7 @@
      */
     public static void parallelPrefix(long[] array, int fromIndex,
                                       int toIndex, LongBinaryOperator op) {
+        Objects.requireNonNull(op);
         rangeCheck(array.length, fromIndex, toIndex);
         if (fromIndex < toIndex)
             new ArrayPrefixHelpers.LongCumulateTask
@@ -1673,6 +1677,7 @@
      * @since 1.8
      */
     public static void parallelPrefix(double[] array, DoubleBinaryOperator op) {
+        Objects.requireNonNull(op);
         if (array.length > 0)
             new ArrayPrefixHelpers.DoubleCumulateTask
                     (null, op, array, 0, array.length).invoke();
@@ -1695,6 +1700,7 @@
      */
     public static void parallelPrefix(double[] array, int fromIndex,
                                       int toIndex, DoubleBinaryOperator op) {
+        Objects.requireNonNull(op);
         rangeCheck(array.length, fromIndex, toIndex);
         if (fromIndex < toIndex)
             new ArrayPrefixHelpers.DoubleCumulateTask
@@ -1716,6 +1722,7 @@
      * @since 1.8
      */
     public static void parallelPrefix(int[] array, IntBinaryOperator op) {
+        Objects.requireNonNull(op);
         if (array.length > 0)
             new ArrayPrefixHelpers.IntCumulateTask
                     (null, op, array, 0, array.length).invoke();
@@ -1738,6 +1745,7 @@
      */
     public static void parallelPrefix(int[] array, int fromIndex,
                                       int toIndex, IntBinaryOperator op) {
+        Objects.requireNonNull(op);
         rangeCheck(array.length, fromIndex, toIndex);
         if (fromIndex < toIndex)
             new ArrayPrefixHelpers.IntCumulateTask
--- a/src/share/classes/java/util/Calendar.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/Calendar.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1937,7 +1937,7 @@
 
     /**
      * Sets the values for the fields <code>YEAR</code>, <code>MONTH</code>,
-     * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, <code>MINUTE</code>, and
+     * <code>DAY_OF_MONTH</code>, <code>HOUR_OF_DAY</code>, <code>MINUTE</code>, and
      * <code>SECOND</code>.
      * Previous values of other fields are retained.  If this is not desired,
      * call {@link #clear()} first.
--- a/src/share/classes/java/util/Collection.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/Collection.java	Tue Oct 08 14:57:32 2013 -0700
@@ -104,6 +104,13 @@
  * the specified behavior of underlying {@link Object} methods wherever the
  * implementor deems it appropriate.
  *
+ * <p>Some collection operations which perform recursive traversal of the
+ * collection may fail with an exception for self-referential instances where
+ * the collection directly or indirectly contains itself. This includes the
+ * {@code clone()}, {@code equals()}, {@code hashCode()} and {@code toString()}
+ * methods. Implementations may optionally handle the self-referential scenario,
+ * however most current implementations do not do so.
+ *
  * <p>This interface is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
@@ -379,8 +386,8 @@
 
     /**
      * Removes all of the elements of this collection that satisfy the given
-     * predicate.  Errors or runtime exceptions thrown by the predicate are
-     * relayed to the caller.
+     * predicate.  Errors or runtime exceptions thrown during iteration or by
+     * the predicate are relayed to the caller.
      *
      * @implSpec
      * The default implementation traverses all elements of the collection using
@@ -393,9 +400,10 @@
      *        removed
      * @return {@code true} if any elements were removed
      * @throws NullPointerException if the specified filter is null
-     * @throws UnsupportedOperationException if the {@code remove}
-     *         method is not supported by this collection's
-     *         {@link #iterator}
+     * @throws UnsupportedOperationException if elements cannot be removed
+     *         from this collection.  Implementations may throw this exception if a
+     *         matching element cannot be removed or if, in general, removal is not
+     *         supported.
      * @since 1.8
      */
     default boolean removeIf(Predicate<? super E> filter) {
@@ -502,12 +510,10 @@
     /**
      * Creates a {@link Spliterator} over the elements in this collection.
      *
-     * <p>The returned {@code Spliterator} must report the characteristic
-     * {@link Spliterator#SIZED}; implementations should document any additional
-     * characteristic values reported by the returned spliterator.  If
-     * this collection contains no elements then the returned spliterator is
-     * only required to report {@link Spliterator#SIZED} and is not required to
-     * report additional characteristic values (if any).
+     * Implementations should document characteristic values reported by the
+     * spliterator.  Such characteristic values are not required to be reported
+     * if the spliterator reports {@link Spliterator#SIZED} and this collection
+     * contains no elements.
      *
      * <p>The default implementation should be overridden by subclasses that
      * can return a more efficient spliterator.  In order to
@@ -533,9 +539,11 @@
      * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
      * from the collections's {@code Iterator}.  The spliterator inherits the
      * <em>fail-fast</em> properties of the collection's iterator.
+     * <p>
+     * The created {@code Spliterator} reports {@link Spliterator#SIZED}.
      *
      * @implNote
-     * The returned {@code Spliterator} additionally reports
+     * The created {@code Spliterator} additionally reports
      * {@link Spliterator#SUBSIZED}.
      *
      * <p>If a spliterator covers no elements then the reporting of additional
--- a/src/share/classes/java/util/GregorianCalendar.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/GregorianCalendar.java	Tue Oct 08 14:57:32 2013 -0700
@@ -41,11 +41,8 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.time.Instant;
-import java.time.ZoneId;
 import java.time.ZonedDateTime;
-import java.time.chrono.IsoChronology;
 import java.time.temporal.ChronoField;
-import java.time.temporal.TemporalQuery;
 import sun.util.calendar.BaseCalendar;
 import sun.util.calendar.CalendarDate;
 import sun.util.calendar.CalendarSystem;
@@ -867,6 +864,7 @@
      * <code>false</code> otherwise.
      * @see Calendar#compareTo(Calendar)
      */
+    @Override
     public boolean equals(Object obj) {
         return obj instanceof GregorianCalendar &&
             super.equals(obj) &&
@@ -876,6 +874,7 @@
     /**
      * Generates the hash code for this <code>GregorianCalendar</code> object.
      */
+    @Override
     public int hashCode() {
         return super.hashCode() ^ (int)gregorianCutoverDate;
     }
@@ -908,6 +907,7 @@
      * or if any calendar fields have out-of-range values in
      * non-lenient mode.
      */
+    @Override
     public void add(int field, int amount) {
         // If amount == 0, do nothing even the given field is out of
         // range. This is tested by JCK.
@@ -1106,6 +1106,7 @@
      * @see #add(int,int)
      * @see #set(int,int)
      */
+    @Override
     public void roll(int field, boolean up) {
         roll(field, up ? +1 : -1);
     }
@@ -1154,6 +1155,7 @@
      * @see #set(int,int)
      * @since 1.2
      */
+    @Override
     public void roll(int field, int amount) {
         // If amount == 0, do nothing even the given field is out of
         // range. This is tested by JCK.
@@ -1272,25 +1274,44 @@
                 int woy = internalGet(WEEK_OF_YEAR);
                 int value = woy + amount;
                 if (!isCutoverYear(y)) {
-                    // If the new value is in between min and max
-                    // (exclusive), then we can use the value.
-                    if (value > min && value < max) {
-                        set(WEEK_OF_YEAR, value);
-                        return;
+                    int weekYear = getWeekYear();
+                    if (weekYear == y) {
+                        // If the new value is in between min and max
+                        // (exclusive), then we can use the value.
+                        if (value > min && value < max) {
+                            set(WEEK_OF_YEAR, value);
+                            return;
+                        }
+                        long fd = getCurrentFixedDate();
+                        // Make sure that the min week has the current DAY_OF_WEEK
+                        // in the calendar year
+                        long day1 = fd - (7 * (woy - min));
+                        if (calsys.getYearFromFixedDate(day1) != y) {
+                            min++;
+                        }
+
+                        // Make sure the same thing for the max week
+                        fd += 7 * (max - internalGet(WEEK_OF_YEAR));
+                        if (calsys.getYearFromFixedDate(fd) != y) {
+                            max--;
+                        }
+                    } else {
+                        // When WEEK_OF_YEAR and YEAR are out of sync,
+                        // adjust woy and amount to stay in the calendar year.
+                        if (weekYear > y) {
+                            if (amount < 0) {
+                                amount++;
+                            }
+                            woy = max;
+                        } else {
+                            if (amount > 0) {
+                                amount -= woy - max;
+                            }
+                            woy = min;
+                        }
                     }
-                    long fd = getCurrentFixedDate();
-                    // Make sure that the min week has the current DAY_OF_WEEK
-                    long day1 = fd - (7 * (woy - min));
-                    if (calsys.getYearFromFixedDate(day1) != y) {
-                        min++;
-                    }
-
-                    // Make sure the same thing for the max week
-                    fd += 7 * (max - internalGet(WEEK_OF_YEAR));
-                    if (calsys.getYearFromFixedDate(fd) != y) {
-                        max--;
-                    }
-                    break;
+                    set(field, getRolledValue(woy, amount, min, max));
+                    return;
                 }
 
                 // Handle cutover here.
@@ -1510,6 +1531,7 @@
      * @see #getActualMinimum(int)
      * @see #getActualMaximum(int)
      */
+    @Override
     public int getMinimum(int field) {
         return MIN_VALUES[field];
     }
@@ -1533,6 +1555,7 @@
      * @see #getActualMinimum(int)
      * @see #getActualMaximum(int)
      */
+    @Override
     public int getMaximum(int field) {
         switch (field) {
         case MONTH:
@@ -1581,6 +1604,7 @@
      * @see #getActualMinimum(int)
      * @see #getActualMaximum(int)
      */
+    @Override
     public int getGreatestMinimum(int field) {
         if (field == DAY_OF_MONTH) {
             BaseCalendar.Date d = getGregorianCutoverDate();
@@ -1610,6 +1634,7 @@
      * @see #getActualMinimum(int)
      * @see #getActualMaximum(int)
      */
+    @Override
     public int getLeastMaximum(int field) {
         switch (field) {
         case MONTH:
@@ -1659,6 +1684,7 @@
      * @see #getActualMaximum(int)
      * @since 1.2
      */
+    @Override
     public int getActualMinimum(int field) {
         if (field == DAY_OF_MONTH) {
             GregorianCalendar gc = getNormalizedCalendar();
@@ -1702,6 +1728,7 @@
      * @see #getActualMinimum(int)
      * @since 1.2
      */
+    @Override
     public int getActualMaximum(int field) {
         final int fieldsForFixedMax = ERA_MASK|DAY_OF_WEEK_MASK|HOUR_MASK|AM_PM_MASK|
             HOUR_OF_DAY_MASK|MINUTE_MASK|SECOND_MASK|MILLISECOND_MASK|
@@ -1970,6 +1997,7 @@
             (internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET));
     }
 
+    @Override
     public Object clone()
     {
         GregorianCalendar other = (GregorianCalendar) super.clone();
@@ -1987,6 +2015,7 @@
         return other;
     }
 
+    @Override
     public TimeZone getTimeZone() {
         TimeZone zone = super.getTimeZone();
         // To share the zone by CalendarDates
@@ -1997,6 +2026,7 @@
         return zone;
     }
 
+    @Override
     public void setTimeZone(TimeZone zone) {
         super.setTimeZone(zone);
         // To share the zone by CalendarDates
@@ -2227,6 +2257,7 @@
      * @see #getActualMaximum(int)
      * @since 1.7
      */
+    @Override
     public int getWeeksInWeekYear() {
         GregorianCalendar gc = getNormalizedCalendar();
         int weekYear = gc.getWeekYear();
@@ -2262,8 +2293,9 @@
      *
      * @see Calendar#complete
      */
+    @Override
     protected void computeFields() {
-        int mask = 0;
+        int mask;
         if (isPartiallyNormalized()) {
             // Determine which calendar fields need to be computed.
             mask = getSetStateFields();
@@ -2598,6 +2630,7 @@
      *
      * @exception IllegalArgumentException if any calendar fields are invalid.
      */
+    @Override
     protected void computeTime() {
         // In non-lenient mode, perform brief checking of calendar
         // fields which have been set externally. Through this
--- a/src/share/classes/java/util/List.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/List.java	Tue Oct 08 14:57:32 2013 -0700
@@ -396,11 +396,13 @@
      * replacing the first element.
      *
      * @param operator the operator to apply to each element
-     * @throws UnsupportedOperationException if the {@code set}
-     *         operation is not supported by this list
+     * @throws UnsupportedOperationException if this list is unmodifiable.
+     *         Implementations may throw this exception if an element
+     *         cannot be replaced or if, in general, modification is not
+     *         supported
      * @throws NullPointerException if the specified operator is null or
-     *         if the element is replaced with a null value and this list
-     *         does not permit null elements
+     *         if the operator result is a null value and this list does
+     *         not permit null elements
      *         (<a href="Collection.html#optional-restrictions">optional</a>)
      * @since 1.8
      */
@@ -685,4 +687,3 @@
         return Spliterators.spliterator(this, Spliterator.ORDERED);
     }
 }
-
--- a/src/share/classes/java/util/Map.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/Map.java	Tue Oct 08 14:57:32 2013 -0700
@@ -86,10 +86,6 @@
  * Such exceptions are marked as "optional" in the specification for this
  * interface.
  *
- * <p>This interface is a member of the
- * <a href="{@docRoot}/../technotes/guides/collections/index.html">
- * Java Collections Framework</a>.
- *
  * <p>Many methods in Collections Framework interfaces are defined
  * in terms of the {@link Object#equals(Object) equals} method.  For
  * example, the specification for the {@link #containsKey(Object)
@@ -107,6 +103,17 @@
  * the specified behavior of underlying {@link Object} methods wherever the
  * implementor deems it appropriate.
  *
+ * <p>Some map operations which perform recursive traversal of the map may fail
+ * with an exception for self-referential instances where the map directly or
+ * indirectly contains itself. This includes the {@code clone()},
+ * {@code equals()}, {@code hashCode()} and {@code toString()} methods.
+ * Implementations may optionally handle the self-referential scenario, however
+ * most current implementations do not do so.
+ *
+ * <p>This interface is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
  * @param <K> the type of keys maintained by this map
  * @param <V> the type of mapped values
  *
--- a/src/share/classes/java/util/Optional.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/Optional.java	Tue Oct 08 14:57:32 2013 -0700
@@ -85,6 +85,7 @@
      * Constructs an instance with the value present.
      *
      * @param value the non-null value to be present
+     * @throws NullPointerException if value is null
      */
     private Optional(T value) {
         this.value = Objects.requireNonNull(value);
@@ -96,6 +97,7 @@
      * @param <T> the class of the value
      * @param value the value to be present, which must be non-null
      * @return an {@code Optional} with the value present
+     * @throws NullPointerException if value is null
      */
     public static <T> Optional<T> of(T value) {
         return new Optional<>(value);
--- a/src/share/classes/java/util/Random.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/Random.java	Tue Oct 08 14:57:32 2013 -0700
@@ -89,7 +89,7 @@
     private static final long addend = 0xBL;
     private static final long mask = (1L << 48) - 1;
 
-    private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+    private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
 
     // IllegalArgumentException messages
     static final String BadBound = "bound must be positive";
--- a/src/share/classes/java/util/Set.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/Set.java	Tue Oct 08 14:57:32 2013 -0700
@@ -386,15 +386,18 @@
     /**
      * Creates a {@code Spliterator} over the elements in this set.
      *
-     * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
-     * {@link Spliterator#DISTINCT}.  Implementations should document the
-     * reporting of additional characteristic values.
+     * <p>The {@code Spliterator} reports {@link Spliterator#DISTINCT}.
+     * Implementations should document the reporting of additional
+     * characteristic values.
      *
      * @implSpec
      * The default implementation creates a
      * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
      * from the set's {@code Iterator}.  The spliterator inherits the
      * <em>fail-fast</em> properties of the set's iterator.
+     * <p>
+     * The created {@code Spliterator} additionally reports
+     * {@link Spliterator#SIZED}.
      *
      * @implNote
      * The created {@code Spliterator} additionally reports
--- a/src/share/classes/java/util/SortedSet.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/SortedSet.java	Tue Oct 08 14:57:32 2013 -0700
@@ -223,10 +223,10 @@
     /**
      * Creates a {@code Spliterator} over the elements in this sorted set.
      *
-     * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
-     * {@link Spliterator#DISTINCT}, {@link Spliterator#SORTED} and
-     * {@link Spliterator#ORDERED}.  Implementations should document the
-     * reporting of additional characteristic values.
+     * <p>The {@code Spliterator} reports {@link Spliterator#DISTINCT},
+     * {@link Spliterator#SORTED} and {@link Spliterator#ORDERED}.
+     * Implementations should document the reporting of additional
+     * characteristic values.
      *
      * <p>The spliterator's comparator (see
      * {@link java.util.Spliterator#getComparator()}) must be {@code null} if
@@ -240,6 +240,9 @@
      * from the sorted set's {@code Iterator}.  The spliterator inherits the
      * <em>fail-fast</em> properties of the set's iterator.  The
      * spliterator's comparator is the same as the sorted set's comparator.
+     * <p>
+     * The created {@code Spliterator} additionally reports
+     * {@link Spliterator#SIZED}.
      *
      * @implNote
      * The created {@code Spliterator} additionally reports
--- a/src/share/classes/java/util/SplittableRandom.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/SplittableRandom.java	Tue Oct 08 14:57:32 2013 -0700
@@ -107,29 +107,25 @@
      * Methods nextLong, nextInt, and derivatives do not return the
      * sequence (seed) values, but instead a hash-like bit-mix of
      * their bits, producing more independently distributed sequences.
-     * For nextLong, the mix64 bit-mixing function computes the same
-     * value as the "64-bit finalizer" function in Austin Appleby's
-     * MurmurHash3 algorithm.  See
-     * http://code.google.com/p/smhasher/wiki/MurmurHash3 , which
-     * comments: "The constants for the finalizers were generated by a
-     * simple simulated-annealing algorithm, and both avalanche all
-     * bits of 'h' to within 0.25% bias." The mix32 function is
-     * equivalent to (int)(mix64(seed) >>> 32), but faster because it
-     * omits a step that doesn't contribute to result.
+     * For nextLong, the mix64 function is based on David Stafford's
+     * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
+     * "Mix13" variant of the "64-bit finalizer" function in Austin
+     * Appleby's MurmurHash3 algorithm (see
+     * http://code.google.com/p/smhasher/wiki/MurmurHash3). The mix32
+     * function is based on Stafford's Mix04 mix function, but returns
+     * the upper 32 bits cast as int.
      *
      * The split operation uses the current generator to form the seed
      * and gamma for another SplittableRandom.  To conservatively
      * avoid potential correlations between seed and value generation,
-     * gamma selection (method nextGamma) uses the "Mix13" constants
-     * for MurmurHash3 described by David Stafford
-     * (http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
-     * To avoid potential weaknesses in bit-mixing transformations, we
-     * restrict gammas to odd values with at least 12 and no more than
-     * 52 bits set.  Rather than rejecting candidates with too few or
-     * too many bits set, method nextGamma flips some bits (which has
-     * the effect of mapping at most 4 to any given gamma value).
-     * This reduces the effective set of 64bit odd gamma values by
-     * about 2<sup>14</sup>, a very tiny percentage, and serves as an
+     * gamma selection (method mixGamma) uses different
+     * (Murmurhash3's) mix constants.  To avoid potential weaknesses
+     * in bit-mixing transformations, we restrict gammas to odd values
+     * with at least 24 0-1 or 1-0 bit transitions.  Rather than
+     * rejecting candidates with too few or too many bits set, method
+     * mixGamma flips some bits (which has the effect of mapping at
+     * most 4 to any given gamma value).  This reduces the effective
+     * set of 64bit odd gamma values by about 2%, and serves as an
      * automated screening for sequence constant selection that is
      * left as an empirical decision in some other hashing and crypto
      * algorithms.
@@ -140,14 +136,15 @@
      * avalanching.
      *
      * The default (no-argument) constructor, in essence, invokes
-     * split() for a common "seeder" SplittableRandom.  Unlike other
-     * cases, this split must be performed in a thread-safe manner, so
-     * we use an AtomicLong to represent the seed rather than use an
-     * explicit SplittableRandom. To bootstrap the seeder, we start
-     * off using a seed based on current time and host unless the
-     * java.util.secureRandomSeed property is set. This serves as a
-     * slimmed-down (and insecure) variant of SecureRandom that also
-     * avoids stalls that may occur when using /dev/random.
+     * split() for a common "defaultGen" SplittableRandom.  Unlike
+     * other cases, this split must be performed in a thread-safe
+     * manner, so we use an AtomicLong to represent the seed rather
+     * than use an explicit SplittableRandom. To bootstrap the
+     * defaultGen, we start off using a seed based on current time and
+     * network interface address unless the java.util.secureRandomSeed
+     * property is set. This serves as a slimmed-down (and insecure)
+     * variant of SecureRandom that also avoids stalls that may occur
+     * when using /dev/random.
      *
      * It is a relatively simple matter to apply the basic design here
      * to use 128 bit seeds. However, emulating 128bit arithmetic and
@@ -160,17 +157,16 @@
      */
 
     /**
-     * The initial gamma value for (unsplit) SplittableRandoms. Must
-     * be odd with at least 12 and no more than 52 bits set. Currently
-     * set to the golden ratio scaled to 64bits.
+     * The golden ratio scaled to 64bits, used as the initial gamma
+     * value for (unsplit) SplittableRandoms.
      */
-    private static final long INITIAL_GAMMA = 0x9e3779b97f4a7c15L;
+    private static final long GOLDEN_GAMMA = 0x9e3779b97f4a7c15L;
 
     /**
      * The least non-zero value returned by nextDouble(). This value
      * is scaled by a random value of 53 bits to produce a result.
      */
-    private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
+    private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53);
 
     /**
      * The seed. Updated only via method nextSeed.
@@ -191,31 +187,31 @@
     }
 
     /**
-     * Computes MurmurHash3 64bit mix function.
+     * Computes Stafford variant 13 of 64bit mix function.
      */
     private static long mix64(long z) {
-        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
-        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
-        return z ^ (z >>> 33);
+        z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
+        z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
+        return z ^ (z >>> 31);
     }
 
     /**
-     * Returns the 32 high bits of mix64(z) as int.
+     * Returns the 32 high bits of Stafford variant 4 mix64 function as int.
      */
     private static int mix32(long z) {
-        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL;
-        return (int)(((z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L) >>> 32);
+        z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
+        return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
     }
 
     /**
      * Returns the gamma value to use for a new split instance.
      */
-    private static long nextGamma(long z) {
-        z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L; // Stafford "Mix13"
-        z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
-        z = (z ^ (z >>> 31)) | 1L; // force to be odd
-        int n = Long.bitCount(z);  // ensure enough 0 and 1 bits
-        return (n < 12 || n > 52) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
+    private static long mixGamma(long z) {
+        z = (z ^ (z >>> 33)) * 0xff51afd7ed558ccdL; // MurmurHash3 mix constants
+        z = (z ^ (z >>> 33)) * 0xc4ceb9fe1a85ec53L;
+        z = (z ^ (z >>> 33)) | 1L;                  // force to be odd
+        int n = Long.bitCount(z ^ (z >>> 1));       // ensure enough transitions
+        return (n < 24) ? z ^ 0xaaaaaaaaaaaaaaaaL : z;
     }
 
     /**
@@ -228,7 +224,7 @@
     /**
      * The seed generator for default constructors.
      */
-    private static final AtomicLong seeder = new AtomicLong(initialSeed());
+    private static final AtomicLong defaultGen = new AtomicLong(initialSeed());
 
     private static long initialSeed() {
         String pp = java.security.AccessController.doPrivileged(
@@ -396,7 +392,7 @@
      * @param seed the initial seed
      */
     public SplittableRandom(long seed) {
-        this(seed, INITIAL_GAMMA);
+        this(seed, GOLDEN_GAMMA);
     }
 
     /**
@@ -405,8 +401,10 @@
      * of those of any other instances in the current program; and
      * may, and typically does, vary across program invocations.
      */
-    public SplittableRandom() { // emulate seeder.split()
-        this.gamma = nextGamma(this.seed = seeder.addAndGet(INITIAL_GAMMA));
+    public SplittableRandom() { // emulate defaultGen.split()
+        long s = defaultGen.getAndAdd(2 * GOLDEN_GAMMA);
+        this.seed = mix64(s);
+        this.gamma = mixGamma(s + GOLDEN_GAMMA);
     }
 
     /**
@@ -424,8 +422,7 @@
      * @return the new SplittableRandom instance
      */
     public SplittableRandom split() {
-        long s = nextSeed();
-        return new SplittableRandom(s, nextGamma(s));
+        return new SplittableRandom(nextLong(), mixGamma(nextSeed()));
     }
 
     /**
--- a/src/share/classes/java/util/concurrent/ThreadLocalRandom.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/concurrent/ThreadLocalRandom.java	Tue Oct 08 14:57:32 2013 -0700
@@ -194,8 +194,8 @@
     private static final long SEEDER_INCREMENT = 0xbb67ae8584caa73bL;
 
     // Constants from SplittableRandom
-    private static final double DOUBLE_UNIT = 1.0 / (1L << 53);
-    private static final float  FLOAT_UNIT  = 1.0f / (1 << 24);
+    private static final double DOUBLE_UNIT = 0x1.0p-53;  // 1.0  / (1L << 53)
+    private static final float  FLOAT_UNIT  = 0x1.0p-24f; // 1.0f / (1 << 24)
 
     /** Rarely-used holder for the second of a pair of Gaussians */
     private static final ThreadLocal<Double> nextLocalGaussian =
--- a/src/share/classes/java/util/stream/Node.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/stream/Node.java	Tue Oct 08 14:57:32 2013 -0700
@@ -149,7 +149,9 @@
     /**
      * Copies the content of this {@code Node} into an array, starting at a
      * given offset into the array.  It is the caller's responsibility to ensure
-     * there is sufficient room in the array.
+     * there is sufficient room in the array, otherwise unspecified behaviour
+     * will occur if the array length is less than the number of elements
+     * contained in this node.
      *
      * @param array the array into which to copy the contents of this
      *       {@code Node}
@@ -258,6 +260,12 @@
          */
         @Override
         default T[] asArray(IntFunction<T[]> generator) {
+            if (java.util.stream.Tripwire.ENABLED)
+                java.util.stream.Tripwire.trip(getClass(), "{0} calling Node.OfPrimitive.asArray");
+
+            long size = count();
+            if (size >= Nodes.MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             T[] boxed = generator.apply((int) count());
             copyInto(boxed, 0);
             return boxed;
--- a/src/share/classes/java/util/stream/Nodes.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/stream/Nodes.java	Tue Oct 08 14:57:32 2013 -0700
@@ -60,6 +60,9 @@
      */
     static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
 
+    // IllegalArgumentException messages
+    static final String BAD_SIZE = "Stream size exceeds max array size";
+
     @SuppressWarnings("raw")
     private static final Node EMPTY_NODE = new EmptyNode.OfRef();
     private static final Node.OfInt EMPTY_INT_NODE = new EmptyNode.OfInt();
@@ -317,7 +320,7 @@
         long size = helper.exactOutputSizeIfKnown(spliterator);
         if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             P_OUT[] array = generator.apply((int) size);
             new SizedCollectorTask.OfRef<>(spliterator, helper, array).invoke();
             return node(array);
@@ -354,7 +357,7 @@
         long size = helper.exactOutputSizeIfKnown(spliterator);
         if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             int[] array = new int[(int) size];
             new SizedCollectorTask.OfInt<>(spliterator, helper, array).invoke();
             return node(array);
@@ -392,7 +395,7 @@
         long size = helper.exactOutputSizeIfKnown(spliterator);
         if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             long[] array = new long[(int) size];
             new SizedCollectorTask.OfLong<>(spliterator, helper, array).invoke();
             return node(array);
@@ -430,7 +433,7 @@
         long size = helper.exactOutputSizeIfKnown(spliterator);
         if (size >= 0 && spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             double[] array = new double[(int) size];
             new SizedCollectorTask.OfDouble<>(spliterator, helper, array).invoke();
             return node(array);
@@ -460,7 +463,10 @@
      */
     public static <T> Node<T> flatten(Node<T> node, IntFunction<T[]> generator) {
         if (node.getChildCount() > 0) {
-            T[] array = generator.apply((int) node.count());
+            long size = node.count();
+            if (size >= MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(BAD_SIZE);
+            T[] array = generator.apply((int) size);
             new ToArrayTask.OfRef<>(node, array, 0).invoke();
             return node(array);
         } else {
@@ -483,7 +489,10 @@
      */
     public static Node.OfInt flattenInt(Node.OfInt node) {
         if (node.getChildCount() > 0) {
-            int[] array = new int[(int) node.count()];
+            long size = node.count();
+            if (size >= MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(BAD_SIZE);
+            int[] array = new int[(int) size];
             new ToArrayTask.OfInt(node, array, 0).invoke();
             return node(array);
         } else {
@@ -506,7 +515,10 @@
      */
     public static Node.OfLong flattenLong(Node.OfLong node) {
         if (node.getChildCount() > 0) {
-            long[] array = new long[(int) node.count()];
+            long size = node.count();
+            if (size >= MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(BAD_SIZE);
+            long[] array = new long[(int) size];
             new ToArrayTask.OfLong(node, array, 0).invoke();
             return node(array);
         } else {
@@ -529,7 +541,10 @@
      */
     public static Node.OfDouble flattenDouble(Node.OfDouble node) {
         if (node.getChildCount() > 0) {
-            double[] array = new double[(int) node.count()];
+            long size = node.count();
+            if (size >= MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(BAD_SIZE);
+            double[] array = new double[(int) size];
             new ToArrayTask.OfDouble(node, array, 0).invoke();
             return node(array);
         } else {
@@ -627,7 +642,7 @@
         @SuppressWarnings("unchecked")
         ArrayNode(long size, IntFunction<T[]> generator) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             this.array = generator.apply((int) size);
             this.curSize = 0;
         }
@@ -777,12 +792,17 @@
         public void copyInto(T[] array, int offset) {
             Objects.requireNonNull(array);
             left.copyInto(array, offset);
+            // Cast to int is safe since it is the callers responsibility to
+            // ensure that there is sufficient room in the array
             right.copyInto(array, offset + (int) left.count());
         }
 
         @Override
         public T[] asArray(IntFunction<T[]> generator) {
-            T[] array = generator.apply((int) count());
+            long size = count();
+            if (size >= MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(BAD_SIZE);
+            T[] array = generator.apply((int) size);
             copyInto(array, 0);
             return array;
         }
@@ -836,12 +856,17 @@
             @Override
             public void copyInto(T_ARR array, int offset) {
                 left.copyInto(array, offset);
+                // Cast to int is safe since it is the callers responsibility to
+                // ensure that there is sufficient room in the array
                 right.copyInto(array, offset + (int) left.count());
             }
 
             @Override
             public T_ARR asPrimitiveArray() {
-                T_ARR array = newArray((int) count());
+                long size = count();
+                if (size >= MAX_ARRAY_SIZE)
+                    throw new IllegalArgumentException(BAD_SIZE);
+                T_ARR array = newArray((int) size);
                 copyInto(array, 0);
                 return array;
             }
@@ -1287,7 +1312,7 @@
 
         IntArrayNode(long size) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             this.array = new int[(int) size];
             this.curSize = 0;
         }
@@ -1343,7 +1368,7 @@
 
         LongArrayNode(long size) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             this.array = new long[(int) size];
             this.curSize = 0;
         }
@@ -1397,7 +1422,7 @@
 
         DoubleArrayNode(long size) {
             if (size >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(BAD_SIZE);
             this.array = new double[(int) size];
             this.curSize = 0;
         }
@@ -1843,8 +1868,8 @@
                 task = task.makeChild(rightSplit, task.offset + leftSplitSize,
                                       task.length - leftSplitSize);
             }
-            if (task.offset + task.length >= MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+
+            assert task.offset + task.length < MAX_ARRAY_SIZE;
             T_SINK sink = (T_SINK) task;
             task.helper.wrapAndCopyInto(sink, rightSplit);
             task.propagateCompletion();
@@ -1854,10 +1879,13 @@
 
         @Override
         public void begin(long size) {
-            if(size > length)
+            if (size > length)
                 throw new IllegalStateException("size passed to Sink.begin exceeds array length");
+            // Casts to int are safe since absolute size is verified to be within
+            // bounds when the root concrete SizedCollectorTask is constructed
+            // with the shared array
             index = (int) offset;
-            fence = (int) offset + (int) length;
+            fence = index + (int) length;
         }
 
         @SuppressWarnings("serial")
--- a/src/share/classes/java/util/stream/SortedOps.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/stream/SortedOps.java	Tue Oct 08 14:57:32 2013 -0700
@@ -278,7 +278,7 @@
     }
 
     /**
-     * {@link ForkJoinTask} for implementing sort on SIZED reference streams.
+     * {@link Sink} for implementing sort on SIZED reference streams.
      */
     private static final class SizedRefSortingSink<T> extends Sink.ChainedReference<T, T> {
         private final Comparator<? super T> comparator;
@@ -293,16 +293,12 @@
         @Override
         public void begin(long size) {
             if (size >= Nodes.MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             array = (T[]) new Object[(int) size];
         }
 
         @Override
         public void end() {
-            // Need to use offset rather than array.length since the downstream
-            // many be short-circuiting
-            // @@@ A better approach is to know if the downstream short-circuits
-            //     and check sink.cancellationRequested
             Arrays.sort(array, 0, offset, comparator);
             downstream.begin(offset);
             for (int i = 0; i < offset; i++)
@@ -331,6 +327,8 @@
 
         @Override
         public void begin(long size) {
+            if (size >= Nodes.MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             list = (size >= 0) ? new ArrayList<T>((int) size) : new ArrayList<T>();
         }
 
@@ -363,7 +361,7 @@
         @Override
         public void begin(long size) {
             if (size >= Nodes.MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             array = new int[(int) size];
         }
 
@@ -395,6 +393,8 @@
 
         @Override
         public void begin(long size) {
+            if (size >= Nodes.MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             b = (size > 0) ? new SpinedBuffer.OfInt((int) size) : new SpinedBuffer.OfInt();
         }
 
@@ -428,7 +428,7 @@
         @Override
         public void begin(long size) {
             if (size >= Nodes.MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             array = new long[(int) size];
         }
 
@@ -460,6 +460,8 @@
 
         @Override
         public void begin(long size) {
+            if (size >= Nodes.MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             b = (size > 0) ? new SpinedBuffer.OfLong((int) size) : new SpinedBuffer.OfLong();
         }
 
@@ -493,7 +495,7 @@
         @Override
         public void begin(long size) {
             if (size >= Nodes.MAX_ARRAY_SIZE)
-                throw new IllegalArgumentException("Stream size exceeds max array size");
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             array = new double[(int) size];
         }
 
@@ -525,6 +527,8 @@
 
         @Override
         public void begin(long size) {
+            if (size >= Nodes.MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
             b = (size > 0) ? new SpinedBuffer.OfDouble((int) size) : new SpinedBuffer.OfDouble();
         }
 
--- a/src/share/classes/java/util/stream/SpinedBuffer.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/stream/SpinedBuffer.java	Tue Oct 08 14:57:32 2013 -0700
@@ -156,6 +156,9 @@
     public E get(long index) {
         // @@@ can further optimize by caching last seen spineIndex,
         // which is going to be right most of the time
+
+        // Casts to int are safe since the spine array index is the index minus
+        // the prior element count from the current spine
         if (spineIndex == 0) {
             if (index < elementIndex)
                 return curChunk[((int) index)];
@@ -201,11 +204,11 @@
      * elements into it.
      */
     public E[] asArray(IntFunction<E[]> arrayFactory) {
-        // @@@ will fail for size == MAX_VALUE
-        E[] result = arrayFactory.apply((int) count());
-
+        long size = count();
+        if (size >= Nodes.MAX_ARRAY_SIZE)
+            throw new IllegalArgumentException(Nodes.BAD_SIZE);
+        E[] result = arrayFactory.apply((int) size);
         copyInto(result, 0);
-
         return result;
     }
 
@@ -547,8 +550,10 @@
         }
 
         public T_ARR asPrimitiveArray() {
-            // @@@ will fail for size == MAX_VALUE
-            T_ARR result = newArray((int) count());
+            long size = count();
+            if (size >= Nodes.MAX_ARRAY_SIZE)
+                throw new IllegalArgumentException(Nodes.BAD_SIZE);
+            T_ARR result = newArray((int) size);
             copyInto(result, 0);
             return result;
         }
@@ -760,11 +765,13 @@
         }
 
         public int get(long index) {
+            // Casts to int are safe since the spine array index is the index minus
+            // the prior element count from the current spine
             int ch = chunkFor(index);
             if (spineIndex == 0 && ch == 0)
                 return curChunk[(int) index];
             else
-                return spine[ch][(int) (index-priorElementCount[ch])];
+                return spine[ch][(int) (index - priorElementCount[ch])];
         }
 
         @Override
@@ -871,11 +878,13 @@
         }
 
         public long get(long index) {
+            // Casts to int are safe since the spine array index is the index minus
+            // the prior element count from the current spine
             int ch = chunkFor(index);
             if (spineIndex == 0 && ch == 0)
                 return curChunk[(int) index];
             else
-                return spine[ch][(int) (index-priorElementCount[ch])];
+                return spine[ch][(int) (index - priorElementCount[ch])];
         }
 
         @Override
@@ -984,11 +993,13 @@
         }
 
         public double get(long index) {
+            // Casts to int are safe since the spine array index is the index minus
+            // the prior element count from the current spine
             int ch = chunkFor(index);
             if (spineIndex == 0 && ch == 0)
                 return curChunk[(int) index];
             else
-                return spine[ch][(int) (index-priorElementCount[ch])];
+                return spine[ch][(int) (index - priorElementCount[ch])];
         }
 
         @Override
--- a/src/share/classes/java/util/stream/Streams.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/java/util/stream/Streams.java	Tue Oct 08 14:57:32 2013 -0700
@@ -169,7 +169,9 @@
 
         private int splitPoint(long size) {
             int d = (size < BALANCED_SPLIT_THRESHOLD) ? 2 : RIGHT_BALANCED_SPLIT_RATIO;
-            // 2 <= size <= 2^32
+            // Cast to int is safe since:
+            //   2 <= size < 2^32
+            //   2 <= d <= 8
             return (int) (size / d);
         }
     }
--- a/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java	Tue Oct 08 14:57:32 2013 -0700
@@ -28,7 +28,7 @@
  * ===========================================================================
  */
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013 Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * $Id: XMLDSigRI.java 1400021 2012-10-19 10:16:04Z coheigea $
@@ -61,7 +61,7 @@
 
     public XMLDSigRI() {
         /* We are the XMLDSig provider */
-        super("XMLDSig", 1.8, INFO);
+        super("XMLDSig", 1.8d, INFO);
 
         final Map<Object, Object> map = new HashMap<Object, Object>();
         map.put("XMLSignatureFactory.DOM",
--- a/src/share/classes/sun/invoke/WrapperInstance.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/invoke/WrapperInstance.java	Tue Oct 08 14:57:32 2013 -0700
@@ -30,7 +30,7 @@
 /**
  * Private API used inside of java.lang.invoke.MethodHandles.
  * Interface implemented by every object which is produced by
- * {@link java.lang.invoke.MethodHandles#asInstance MethodHandles.asInstance}.
+ * {@link java.lang.invoke.MethodHandleProxies#asInterfaceInstance MethodHandleProxies.asInterfaceInstance}.
  * The methods of this interface allow a caller to recover the parameters
  * to {@code asInstance}.
  * This allows applications to repeatedly convert between method handles
--- a/src/share/classes/sun/invoke/util/ValueConversions.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/invoke/util/ValueConversions.java	Tue Oct 08 14:57:32 2013 -0700
@@ -502,51 +502,6 @@
         }
     }
 
-    static MethodHandle collectArguments(MethodHandle mh, int pos, MethodHandle collector) {
-        // FIXME: API needs public MHs.collectArguments.
-        // Should be:
-        //   return MethodHandles.collectArguments(mh, 0, collector);
-        // The rest of this code is a workaround for not having that API.
-        if (COLLECT_ARGUMENTS != null) {
-            try {
-                return (MethodHandle)
-                    COLLECT_ARGUMENTS.invokeExact(mh, pos, collector);
-            } catch (Throwable ex) {
-                if (ex instanceof RuntimeException)
-                    throw (RuntimeException) ex;
-                if (ex instanceof Error)
-                    throw (Error) ex;
-                throw new Error(ex.getMessage(), ex);
-            }
-        }
-        // Emulate MHs.collectArguments using fold + drop.
-        // This is slightly inefficient.
-        // More seriously, it can put a MH over the 255-argument limit.
-        mh = MethodHandles.dropArguments(mh, 1, collector.type().parameterList());
-        mh = MethodHandles.foldArguments(mh, collector);
-        return mh;
-    }
-    private static final MethodHandle COLLECT_ARGUMENTS;
-    static {
-        MethodHandle mh = null;
-        try {
-            final java.lang.reflect.Method m = MethodHandles.class
-                .getDeclaredMethod("collectArguments",
-                    MethodHandle.class, int.class, MethodHandle.class);
-            AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                    @Override
-                    public Void run() {
-                        m.setAccessible(true);
-                        return null;
-                    }
-                });
-            mh = IMPL_LOOKUP.unreflect(m);
-        } catch (ReflectiveOperationException ex) {
-            throw newInternalError(ex);
-        }
-        COLLECT_ARGUMENTS = mh;
-    }
-
     private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
             = newWrapperCaches(1);
 
@@ -1050,12 +1005,12 @@
             if (mh == ARRAY_IDENTITY)
                 mh = rightFiller;
             else
-                mh = collectArguments(mh, 0, rightFiller);
+                mh = MethodHandles.collectArguments(mh, 0, rightFiller);
         }
         if (mh == ARRAY_IDENTITY)
             mh = leftCollector;
         else
-            mh = collectArguments(mh, 0, leftCollector);
+            mh = MethodHandles.collectArguments(mh, 0, leftCollector);
         return mh;
     }
 
@@ -1101,7 +1056,7 @@
         if (midLen == LEFT_ARGS)
             return rightFill;
         else
-            return collectArguments(rightFill, 0, midFill);
+            return MethodHandles.collectArguments(rightFill, 0, midFill);
     }
 
     // Type-polymorphic version of varargs maker.
--- a/src/share/classes/sun/invoke/util/VerifyAccess.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/invoke/util/VerifyAccess.java	Tue Oct 08 14:57:32 2013 -0700
@@ -172,7 +172,7 @@
      * Decide if the given method type, attributed to a member or symbolic
      * reference of a given reference class, is really visible to that class.
      * @param type the supposed type of a member or symbolic reference of refc
-     * @param refc
+     * @param refc the class attempting to make the reference
      */
     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
         if (type == refc)  return true;  // easy check
@@ -197,7 +197,7 @@
      * Decide if the given method type, attributed to a member or symbolic
      * reference of a given reference class, is really visible to that class.
      * @param type the supposed type of a member or symbolic reference of refc
-     * @param refc
+     * @param refc the class attempting to make the reference
      */
     public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) {
         for (int n = -1, max = type.parameterCount(); n < max; n++) {
@@ -210,8 +210,8 @@
 
     /**
      * Test if two classes have the same class loader and package qualifier.
-     * @param class1
-     * @param class2
+     * @param class1 a class
+     * @param class2 another class
      * @return whether they are in the same package
      */
     public static boolean isSamePackage(Class<?> class1, Class<?> class2) {
@@ -244,8 +244,8 @@
     /**
      * Test if two classes are defined as part of the same package member (top-level class).
      * If this is true, they can share private access with each other.
-     * @param class1
-     * @param class2
+     * @param class1 a class
+     * @param class2 another class
      * @return whether they are identical or nested together
      */
     public static boolean isSamePackageMember(Class<?> class1, Class<?> class2) {
@@ -287,8 +287,8 @@
     /**
      * Is the class loader of parentClass identical to, or an ancestor of,
      * the class loader of childClass?
-     * @param parentClass
-     * @param childClass
+     * @param parentClass a class
+     * @param childClass another class, which may be a descendent of the first class
      * @return whether parentClass precedes or equals childClass in class loader order
      */
     public static boolean classLoaderIsAncestor(Class<?> parentClass, Class<?> childClass) {
--- a/src/share/classes/sun/invoke/util/VerifyType.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/invoke/util/VerifyType.java	Tue Oct 08 14:57:32 2013 -0700
@@ -41,8 +41,8 @@
      * True if a value can be stacked as the source type and unstacked as the
      * destination type, without violating the JVM's type consistency.
      *
-     * @param call the type of a stacked value
-     * @param recv the type by which we'd like to treat it
+     * @param src the type of a stacked value
+     * @param dst the type by which we'd like to treat it
      * @return whether the retyping can be done without motion or reformatting
      */
     public static boolean isNullConversion(Class<?> src, Class<?> dst) {
@@ -67,9 +67,8 @@
 
     /**
      * Specialization of isNullConversion to reference types.
-
-     * @param call the type of a stacked value
-     * @param recv the reference type by which we'd like to treat it
+     * @param src the type of a stacked value
+     * @param dst the reference type by which we'd like to treat it
      * @return whether the retyping can be done without a cast
      */
     public static boolean isNullReferenceConversion(Class<?> src, Class<?> dst) {
--- a/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java	Tue Oct 08 14:57:32 2013 -0700
@@ -118,6 +118,7 @@
 
     static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION,
                                                             new TypeAnnotation[0], new TypeAnnotation[0], null);
+    static final AnnotatedType[] EMPTY_ANNOTATED_TYPE_ARRAY = new AnnotatedType[0];
 
     private static class AnnotatedTypeBaseImpl implements AnnotatedType {
         private final Type type;
--- a/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java	Tue Oct 08 14:57:32 2013 -0700
@@ -128,14 +128,18 @@
         for (int i = 0; i < size; i++) {
             @SuppressWarnings("unchecked")
             ArrayList<TypeAnnotation> list = l[i];
+            TypeAnnotation[] typeAnnotations;
             if (list != null) {
-                TypeAnnotation[] typeAnnotations = list.toArray(new TypeAnnotation[0]);
-                result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
-                                                                    LocationInfo.BASE_LOCATION,
-                                                                    typeAnnotations,
-                                                                    typeAnnotations,
-                                                                    decl);
+                typeAnnotations = list.toArray(new TypeAnnotation[list.size()]);
+            } else {
+                typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY;
             }
+            result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
+                                                                LocationInfo.BASE_LOCATION,
+                                                                typeAnnotations,
+                                                                typeAnnotations,
+                                                                decl);
+
         }
         return result;
     }
@@ -174,6 +178,11 @@
     public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations,
             ConstantPool cp,
             Class<?> decl) {
+        if (decl == Object.class ||
+                decl.isArray() ||
+                decl.isPrimitive() ||
+                decl == Void.TYPE)
+            return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE_ARRAY;
         return buildAnnotatedTypes(rawAnnotations,
                                    cp,
                                    decl,
--- a/src/share/classes/sun/security/ec/SunEC.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ec/SunEC.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -67,7 +67,7 @@
     }
 
     public SunEC() {
-        super("SunEC", 1.7d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
+        super("SunEC", 1.8d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
 
         // if there is no security manager installed, put directly into
         // the provider. Otherwise, create a temporary map and use a
--- a/src/share/classes/sun/security/jgss/SunProvider.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/jgss/SunProvider.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2006, 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
@@ -62,7 +62,7 @@
 
     public SunProvider() {
         /* We are the Sun JGSS provider */
-        super("SunJGSS", 1.7d, INFO);
+        super("SunJGSS", 1.8d, INFO);
 
         AccessController.doPrivileged(
                         new java.security.PrivilegedAction<Void>() {
--- a/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java	Tue Oct 08 14:57:32 2013 -0700
@@ -525,6 +525,10 @@
 
                 // get the mechanism token
                 byte[] mechToken = initToken.getMechToken();
+                if (mechToken == null) {
+                    throw new GSSException(GSSException.FAILURE, -1,
+                            "mechToken is missing");
+                }
 
                 /*
                  * Select the best match between the list of mechs
--- a/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -120,7 +120,7 @@
 
     public SunNativeProvider() {
         /* We are the Sun NativeGSS provider */
-        super(NAME, 1.0, INFO);
+        super(NAME, 1.8d, INFO);
 
         if (MECH_MAP != null) {
             AccessController.doPrivileged(new PutAllAction(this, MECH_MAP));
--- a/src/share/classes/sun/security/pkcs11/Secmod.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/pkcs11/Secmod.java	Tue Oct 08 14:57:32 2013 -0700
@@ -756,8 +756,12 @@
             if (DEBUG) System.out.println("handles: " + handles.length);
 
             for (long handle : handles) {
-                TrustAttributes trust = new TrustAttributes(token, session, handle);
-                trustMap.put(trust.getHash(), trust);
+                try {
+                    TrustAttributes trust = new TrustAttributes(token, session, handle);
+                    trustMap.put(trust.getHash(), trust);
+                } catch (PKCS11Exception e) {
+                    // skip put on pkcs11 error
+                }
             }
         } finally {
             token.releaseSession(session);
--- a/src/share/classes/sun/security/pkcs11/SunPKCS11.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/pkcs11/SunPKCS11.java	Tue Oct 08 14:57:32 2013 -0700
@@ -94,7 +94,7 @@
     }
 
     public SunPKCS11() {
-        super("SunPKCS11-Dummy", 1.7d, "SunPKCS11-Dummy");
+        super("SunPKCS11-Dummy", 1.8d, "SunPKCS11-Dummy");
         throw new ProviderException
             ("SunPKCS11 requires configuration file argument");
     }
@@ -127,7 +127,7 @@
     public SunPKCS11(String configName, InputStream configStream) {
         super("SunPKCS11-" +
             Config.getConfig(configName, configStream).getName(),
-            1.7d, Config.getConfig(configName, configStream).getDescription());
+            1.8d, Config.getConfig(configName, configStream).getDescription());
         this.configName = configName;
         this.config = Config.removeConfig(configName);
 
--- a/src/share/classes/sun/security/provider/MD4.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/provider/MD4.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -65,7 +65,7 @@
     private final static Provider md4Provider;
 
     static {
-        md4Provider = new Provider("MD4Provider", 1.0d, "MD4 MessageDigest") {
+        md4Provider = new Provider("MD4Provider", 1.8d, "MD4 MessageDigest") {
             private static final long serialVersionUID = -8850464997518327965L;
         };
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
--- a/src/share/classes/sun/security/provider/Sun.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/provider/Sun.java	Tue Oct 08 14:57:32 2013 -0700
@@ -47,7 +47,7 @@
 
     public Sun() {
         /* We are the SUN provider */
-        super("SUN", 1.8, INFO);
+        super("SUN", 1.8d, INFO);
 
         // if there is no security manager installed, put directly into
         // the provider. Otherwise, create a temporary map and use a
--- a/src/share/classes/sun/security/provider/VerificationProvider.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/provider/VerificationProvider.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -61,7 +61,7 @@
     }
 
     public VerificationProvider() {
-        super("SunJarVerification", 1.7, "Jar Verification Provider");
+        super("SunJarVerification", 1.8d, "Jar Verification Provider");
         // register all algorithms normally registered by the Sun and SunRsaSign
         // providers, but only if they are missing
         if (ACTIVE == false) {
--- a/src/share/classes/sun/security/rsa/SunRsaSign.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/rsa/SunRsaSign.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -43,7 +43,7 @@
     private static final long serialVersionUID = 866040293550393045L;
 
     public SunRsaSign() {
-        super("SunRsaSign", 1.7d, "Sun RSA signature provider");
+        super("SunRsaSign", 1.8d, "Sun RSA signature provider");
 
         // if there is no security manager installed, put directly into
         // the provider. Otherwise, create a temporary map and use a
--- a/src/share/classes/sun/security/smartcardio/SunPCSC.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/smartcardio/SunPCSC.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -40,7 +40,7 @@
     private static final long serialVersionUID = 6168388284028876579L;
 
     public SunPCSC() {
-        super("SunPCSC", 1.7d, "Sun PC/SC provider");
+        super("SunPCSC", 1.8d, "Sun PC/SC provider");
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
             public Void run() {
                 put("TerminalFactory.PC/SC", "sun.security.smartcardio.SunPCSC$Factory");
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -92,6 +92,8 @@
     private List<SNIServerName> requestedServerNames =
             Collections.<SNIServerName>emptyList();
 
+    private boolean serverNamesAccepted = false;
+
     /*
      * Constructors
      */
@@ -567,7 +569,9 @@
         // check extensions
         for (HelloExtension ext : mesg.extensions.list()) {
             ExtensionType type = ext.type;
-            if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
+            if (type == ExtensionType.EXT_SERVER_NAME) {
+                serverNamesAccepted = true;
+            } else if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
                     && (type != ExtensionType.EXT_EC_POINT_FORMATS)
                     && (type != ExtensionType.EXT_SERVER_NAME)
                     && (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
@@ -864,15 +868,47 @@
             break;
         case K_KRB5:
         case K_KRB5_EXPORT:
-            String hostname = getHostSE();
-            if (hostname == null) {
-                throw new IOException("Hostname is required" +
-                                " to use Kerberos cipher suites");
+            String sniHostname = null;
+            for (SNIServerName serverName : requestedServerNames) {
+                if (serverName instanceof SNIHostName) {
+                    sniHostname = ((SNIHostName) serverName).getAsciiName();
+                    break;
+                }
             }
-            KerberosClientKeyExchange kerberosMsg =
-                new KerberosClientKeyExchange(
-                    hostname, isLoopbackSE(), getAccSE(), protocolVersion,
-                sslContext.getSecureRandom());
+
+            KerberosClientKeyExchange kerberosMsg = null;
+            if (sniHostname != null) {
+                // use first requested SNI hostname
+                try {
+                    kerberosMsg = new KerberosClientKeyExchange(
+                        sniHostname, getAccSE(), protocolVersion,
+                        sslContext.getSecureRandom());
+                } catch(IOException e) {
+                    if (serverNamesAccepted) {
+                        // server accepted requested SNI hostname,
+                        // so it must be used
+                        throw e;
+                    }
+                    // fallback to using hostname
+                    if (debug != null && Debug.isOn("handshake")) {
+                        System.out.println(
+                            "Warning, cannot use Server Name Indication: "
+                                + e.getMessage());
+                    }
+                }
+            }
+
+            if (kerberosMsg == null) {
+                String hostname = getHostSE();
+                if (hostname == null) {
+                    throw new IOException("Hostname is required" +
+                        " to use Kerberos cipher suites");
+                }
+                kerberosMsg = new KerberosClientKeyExchange(
+                     hostname, getAccSE(), protocolVersion,
+                     sslContext.getSecureRandom());
+            }
+
             // Record the principals involved in exchange
             session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
             session.setLocalPrincipal(kerberosMsg.getLocalPrincipal());
--- a/src/share/classes/sun/security/ssl/Handshaker.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ssl/Handshaker.java	Tue Oct 08 14:57:32 2013 -0700
@@ -335,14 +335,6 @@
         }
     }
 
-    boolean isLoopbackSE() {
-        if (conn != null) {
-            return conn.getInetAddress().isLoopbackAddress();
-        } else {
-            return false;
-        }
-    }
-
     int getPortSE() {
         if (conn != null) {
             return conn.getPort();
--- a/src/share/classes/sun/security/ssl/JsseJce.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ssl/JsseJce.java	Tue Oct 08 14:57:32 2013 -0700
@@ -110,7 +110,7 @@
         private static final long serialVersionUID = -3284138292032213752L;
 
         SunCertificates(final Provider p) {
-            super("SunCertificates", 1.0d, "SunJSSE internal");
+            super("SunCertificates", 1.8d, "SunJSSE internal");
             AccessController.doPrivileged(new PrivilegedAction<Object>() {
                 @Override
                 public Object run() {
--- a/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java	Tue Oct 08 14:57:32 2013 -0700
@@ -77,12 +77,12 @@
         // please won't check the value of impl variable
     }
 
-    public KerberosClientKeyExchange(String serverName, boolean isLoopback,
+    public KerberosClientKeyExchange(String serverName,
         AccessControlContext acc, ProtocolVersion protocolVersion,
         SecureRandom rand) throws IOException {
 
         if (impl != null) {
-            init(serverName, isLoopback, acc, protocolVersion, rand);
+            init(serverName, acc, protocolVersion, rand);
         } else {
             throw new IllegalStateException("Kerberos is unavailable");
         }
@@ -120,12 +120,12 @@
         impl.print(p);
     }
 
-    public void init(String serverName, boolean isLoopback,
+    public void init(String serverName,
         AccessControlContext acc, ProtocolVersion protocolVersion,
         SecureRandom rand) throws IOException {
 
         if (impl != null) {
-            impl.init(serverName, isLoopback, acc, protocolVersion, rand);
+            impl.init(serverName, acc, protocolVersion, rand);
         }
     }
 
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java	Tue Oct 08 14:57:32 2013 -0700
@@ -40,6 +40,8 @@
 
 import javax.security.auth.Subject;
 
+import sun.security.util.KeyUtil;
+import sun.security.action.GetPropertyAction;
 import sun.security.ssl.HandshakeMessage.*;
 import sun.security.ssl.CipherSuite.*;
 import sun.security.ssl.SignatureAndHashAlgorithm.*;
@@ -93,6 +95,50 @@
     // the preferable signature algorithm used by ServerKeyExchange message
     SignatureAndHashAlgorithm preferableSignatureAlgorithm;
 
+    // Flag to use smart ephemeral DH key which size matches the corresponding
+    // authentication key
+    private static final boolean useSmartEphemeralDHKeys;
+
+    // Flag to use legacy ephemeral DH key which size is 512 bits for
+    // exportable cipher suites, and 768 bits for others
+    private static final boolean useLegacyEphemeralDHKeys;
+
+    // The customized ephemeral DH key size for non-exportable cipher suites.
+    private static final int customizedDHKeySize;
+
+    static {
+        String property = AccessController.doPrivileged(
+                    new GetPropertyAction("jdk.tls.ephemeralDHKeySize"));
+        if (property == null || property.length() == 0) {
+            useLegacyEphemeralDHKeys = false;
+            useSmartEphemeralDHKeys = false;
+            customizedDHKeySize = -1;
+        } else if ("matched".equals(property)) {
+            useLegacyEphemeralDHKeys = false;
+            useSmartEphemeralDHKeys = true;
+            customizedDHKeySize = -1;
+        } else if ("legacy".equals(property)) {
+            useLegacyEphemeralDHKeys = true;
+            useSmartEphemeralDHKeys = false;
+            customizedDHKeySize = -1;
+        } else {
+            useLegacyEphemeralDHKeys = false;
+            useSmartEphemeralDHKeys = false;
+
+            try {
+                customizedDHKeySize = Integer.parseUnsignedInt(property);
+                if (customizedDHKeySize < 1024 || customizedDHKeySize > 2048) {
+                    throw new IllegalArgumentException(
+                        "Customized DH key size should be positive integer " +
+                        "between 1024 and 2048 bits, inclusive");
+                }
+            } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException(
+                        "Invalid system property jdk.tls.ephemeralDHKeySize");
+            }
+        }
+    }
+
     /*
      * Constructor ... use the keys found in the auth context.
      */
@@ -1107,7 +1153,7 @@
                 }
             }
 
-            setupEphemeralDHKeys(suite.exportable);
+            setupEphemeralDHKeys(suite.exportable, privateKey);
             break;
         case K_ECDHE_RSA:
             // need RSA certs for authentication
@@ -1144,7 +1190,8 @@
             if (setupPrivateKeyAndChain("DSA") == false) {
                 return false;
             }
-            setupEphemeralDHKeys(suite.exportable);
+
+            setupEphemeralDHKeys(suite.exportable, privateKey);
             break;
         case K_ECDHE_ECDSA:
             // get preferable peer signature algorithm for server key exchange
@@ -1188,7 +1235,7 @@
             break;
         case K_DH_ANON:
             // no certs needed for anonymous
-            setupEphemeralDHKeys(suite.exportable);
+            setupEphemeralDHKeys(suite.exportable, null);
             break;
         case K_ECDH_ANON:
             // no certs needed for anonymous
@@ -1237,15 +1284,70 @@
      * Acquire some "ephemeral" Diffie-Hellman  keys for this handshake.
      * We don't reuse these, for improved forward secrecy.
      */
-    private void setupEphemeralDHKeys(boolean export) {
+    private void setupEphemeralDHKeys(boolean export, Key key) {
         /*
-         * Diffie-Hellman keys ... we use 768 bit private keys due
-         * to the "use twice as many key bits as bits you want secret"
-         * rule of thumb, assuming we want the same size premaster
-         * secret with Diffie-Hellman and RSA key exchanges.  Except
-         * that exportable ciphers max out at 512 bits modulus values.
+         * 768 bits ephemeral DH private keys were used to be used in
+         * ServerKeyExchange except that exportable ciphers max out at 512
+         * bits modulus values. We still adhere to this behavior in legacy
+         * mode (system property "jdk.tls.ephemeralDHKeySize" is defined
+         * as "legacy").
+         *
+         * Old JDK (JDK 7 and previous) releases don't support DH keys bigger
+         * than 1024 bits. We have to consider the compatibility requirement.
+         * 1024 bits DH key is always used for non-exportable cipher suites
+         * in default mode (system property "jdk.tls.ephemeralDHKeySize"
+         * is not defined).
+         *
+         * However, if applications want more stronger strength, setting
+         * system property "jdk.tls.ephemeralDHKeySize" to "matched"
+         * is a workaround to use ephemeral DH key which size matches the
+         * corresponding authentication key. For example, if the public key
+         * size of an authentication certificate is 2048 bits, then the
+         * ephemeral DH key size should be 2048 bits accordingly unless
+         * the cipher suite is exportable.  This key sizing scheme keeps
+         * the cryptographic strength consistent between authentication
+         * keys and key-exchange keys.
+         *
+         * Applications may also want to customize the ephemeral DH key size
+         * to a fixed length for non-exportable cipher suites. This can be
+         * approached by setting system property "jdk.tls.ephemeralDHKeySize"
+         * to a valid positive integer between 1024 and 2048 bits, inclusive.
+         *
+         * Note that the minimum acceptable key size is 1024 bits except
+         * exportable cipher suites or legacy mode.
+         *
+         * Note that the maximum acceptable key size is 2048 bits because
+         * DH keys bigger than 2048 are not always supported by underlying
+         * JCE providers.
+         *
+         * Note that per RFC 2246, the key size limit of DH is 512 bits for
+         * exportable cipher suites.  Because of the weakness, exportable
+         * cipher suites are deprecated since TLS v1.1 and they are not
+         * enabled by default in Oracle provider. The legacy behavior is
+         * reserved and 512 bits DH key is always used for exportable
+         * cipher suites.
          */
-        dh = new DHCrypt((export ? 512 : 768), sslContext.getSecureRandom());
+        int keySize = export ? 512 : 1024;           // default mode
+        if (!export) {
+            if (useLegacyEphemeralDHKeys) {          // legacy mode
+                keySize = 768;
+            } else if (useSmartEphemeralDHKeys) {    // matched mode
+                if (key != null) {
+                    int ks = KeyUtil.getKeySize(key);
+                    // Note that SunJCE provider only supports 2048 bits DH
+                    // keys bigger than 1024.  Please DON'T use value other
+                    // than 1024 and 2048 at present.  We may improve the
+                    // underlying providers and key size here in the future.
+                    //
+                    // keySize = ks <= 1024 ? 1024 : (ks >= 2048 ? 2048 : ks);
+                    keySize = ks <= 1024 ? 1024 : 2048;
+                } // Otherwise, anonymous cipher suites, 1024-bit is used.
+            } else if (customizedDHKeySize > 0) {    // customized mode
+                keySize = customizedDHKeySize;
+            }
+        }
+
+        dh = new DHCrypt(keySize, sslContext.getSecureRandom());
     }
 
     // Setup the ephemeral ECDH parameters.
--- a/src/share/classes/sun/security/ssl/SunJSSE.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ssl/SunJSSE.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -131,7 +131,7 @@
 
     private SunJSSE(java.security.Provider cryptoProvider,
             String providerName) {
-        super("SunJSSE", 1.6d, fipsInfo + providerName + ")");
+        super("SunJSSE", 1.8d, fipsInfo + providerName + ")");
         subclassCheck();
         if (cryptoProvider == null) {
             // Calling Security.getProvider() will cause other providers to be
--- a/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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,12 +105,12 @@
      *          secret
      */
     @Override
-    public void init(String serverName, boolean isLoopback,
+    public void init(String serverName,
         AccessControlContext acc, ProtocolVersion protocolVersion,
         SecureRandom rand) throws IOException {
 
          // Get service ticket
-         KerberosTicket ticket = getServiceTicket(serverName, isLoopback, acc);
+         KerberosTicket ticket = getServiceTicket(serverName, acc);
          encodedTicket = ticket.getEncoded();
 
          // Record the Kerberos principals
@@ -292,25 +292,33 @@
     }
 
     // Similar to sun.security.jgss.krb5.Krb5InitCredenetial/Krb5Context
-    private static KerberosTicket getServiceTicket(String srvName,
-        boolean isLoopback, final AccessControlContext acc) throws IOException {
+    private static KerberosTicket getServiceTicket(String serverName,
+        final AccessControlContext acc) throws IOException {
 
-        // get the local hostname if srvName is loopback address
-        String serverName = srvName;
-        if (isLoopback) {
+        if ("localhost".equals(serverName) ||
+                "localhost.localdomain".equals(serverName)) {
+
+            if (debug != null && Debug.isOn("handshake")) {
+                System.out.println("Get the local hostname");
+            }
             String localHost = java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedAction<String>() {
                 public String run() {
-                    String hostname;
                     try {
-                        hostname = InetAddress.getLocalHost().getHostName();
+                        return InetAddress.getLocalHost().getHostName();
                     } catch (java.net.UnknownHostException e) {
-                        hostname = "localhost";
+                        if (debug != null && Debug.isOn("handshake")) {
+                            System.out.println("Warning,"
+                                + " cannot get the local hostname: "
+                                + e.getMessage());
+                        }
+                        return null;
                     }
-                    return hostname;
                 }
             });
-          serverName = localHost;
+            if (localHost != null) {
+                serverName = localHost;
+            }
         }
 
         // Resolve serverName (possibly in IP addr form) to Kerberos principal
--- a/src/share/classes/sun/security/tools/keytool/Main.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/tools/keytool/Main.java	Tue Oct 08 14:57:32 2013 -0700
@@ -72,6 +72,8 @@
 import sun.security.util.Password;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
 
 import sun.security.pkcs.PKCS9Attribute;
 import sun.security.tools.KeyStoreUtil;
@@ -190,6 +192,10 @@
             KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
             PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
             PROVIDERPATH, V),
+        IMPORTPASS("Imports.a.password",
+            ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
+            STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
+            PROVIDERARG, PROVIDERPATH, V, PROTECTED),
         IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
             SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
             DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
@@ -409,6 +415,8 @@
                 command = GENKEYPAIR;
             } else if (collator.compare(flags, "-import") == 0) {
                 command = IMPORTCERT;
+            } else if (collator.compare(flags, "-importpassword") == 0) {
+                command = IMPORTPASS;
             }
             /*
              * Help
@@ -727,6 +735,7 @@
                         command != GENSECKEY &&
                         command != IDENTITYDB &&
                         command != IMPORTCERT &&
+                        command != IMPORTPASS &&
                         command != IMPORTKEYSTORE &&
                         command != PRINTCRL) {
                         throw new Exception(rb.getString
@@ -808,6 +817,7 @@
                         command == GENKEYPAIR ||
                         command == GENSECKEY ||
                         command == IMPORTCERT ||
+                        command == IMPORTPASS ||
                         command == IMPORTKEYSTORE ||
                         command == KEYCLONE ||
                         command == CHANGEALIAS ||
@@ -958,6 +968,13 @@
             }
             doGenSecretKey(alias, keyAlgName, keysize);
             kssave = true;
+        } else if (command == IMPORTPASS) {
+            if (keyAlgName == null) {
+                keyAlgName = "PBE";
+            }
+            // password is stored as a secret key
+            doGenSecretKey(alias, keyAlgName, keysize);
+            kssave = true;
         } else if (command == IDENTITYDB) {
             if (filename != null) {
                 try (InputStream inStream = new FileInputStream(filename)) {
@@ -1419,6 +1436,43 @@
         }
         return null;    // PKCS11, MSCAPI, or -protected
     }
+
+    /*
+     * Prompt the user for the password credential to be stored.
+     */
+    private char[] promptForCredential() throws Exception {
+        // Handle password supplied via stdin
+        if (System.console() == null) {
+            char[] importPass = Password.readPassword(System.in);
+            passwords.add(importPass);
+            return importPass;
+        }
+
+        int count;
+        for (count = 0; count < 3; count++) {
+            System.err.print(
+                rb.getString("Enter.the.password.to.be.stored."));
+            System.err.flush();
+            char[] entered = Password.readPassword(System.in);
+            passwords.add(entered);
+            System.err.print(rb.getString("Re.enter.password."));
+            char[] passAgain = Password.readPassword(System.in);
+            passwords.add(passAgain);
+            if (!Arrays.equals(entered, passAgain)) {
+                System.err.println(rb.getString("They.don.t.match.Try.again"));
+                continue;
+            }
+            return entered;
+        }
+
+        if (count == 3) {
+            throw new Exception(rb.getString
+                ("Too.many.failures.key.not.added.to.keystore"));
+        }
+
+        return null;
+    }
+
     /**
      * Creates a new secret key.
      */
@@ -1436,24 +1490,63 @@
             throw new Exception(form.format(source));
         }
 
+        // Use the keystore's default PBE algorithm for entry protection
+        boolean useDefaultPBEAlgorithm = true;
         SecretKey secKey = null;
-        KeyGenerator keygen = KeyGenerator.getInstance(keyAlgName);
-        if (keysize != -1) {
+
+        if (keyAlgName.toUpperCase().startsWith("PBE")) {
+            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
+
+            // User is prompted for PBE credential
+            secKey =
+                factory.generateSecret(new PBEKeySpec(promptForCredential()));
+
+            // Check whether a specific PBE algorithm was specified
+            if (!"PBE".equalsIgnoreCase(keyAlgName)) {
+                useDefaultPBEAlgorithm = false;
+            }
+
+            if (verbose) {
+                MessageFormat form = new MessageFormat(rb.getString(
+                    "Generated.keyAlgName.secret.key"));
+                Object[] source =
+                    {useDefaultPBEAlgorithm ? "PBE" : secKey.getAlgorithm()};
+                System.err.println(form.format(source));
+            }
+        } else {
+            KeyGenerator keygen = KeyGenerator.getInstance(keyAlgName);
+            if (keysize == -1) {
+                if ("DES".equalsIgnoreCase(keyAlgName)) {
+                    keysize = 56;
+                } else if ("DESede".equalsIgnoreCase(keyAlgName)) {
+                    keysize = 168;
+                } else {
+                    throw new Exception(rb.getString
+                        ("Please.provide.keysize.for.secret.key.generation"));
+                }
+            }
             keygen.init(keysize);
-        } else if ("DES".equalsIgnoreCase(keyAlgName)) {
-            keygen.init(56);
-        } else if ("DESede".equalsIgnoreCase(keyAlgName)) {
-            keygen.init(168);
-        } else {
-            throw new Exception(rb.getString
-                ("Please.provide.keysize.for.secret.key.generation"));
+            secKey = keygen.generateKey();
+
+            if (verbose) {
+                MessageFormat form = new MessageFormat(rb.getString
+                    ("Generated.keysize.bit.keyAlgName.secret.key"));
+                Object[] source = {new Integer(keysize),
+                                    secKey.getAlgorithm()};
+                System.err.println(form.format(source));
+            }
         }
 
-        secKey = keygen.generateKey();
         if (keyPass == null) {
             keyPass = promptForKeyPass(alias, null, storePass);
         }
-        keyStore.setKeyEntry(alias, secKey, keyPass, null);
+
+        if (useDefaultPBEAlgorithm) {
+            keyStore.setKeyEntry(alias, secKey, keyPass, null);
+        } else {
+            keyStore.setEntry(alias, new KeyStore.SecretKeyEntry(secKey),
+                new KeyStore.PasswordProtection(keyPass, keyAlgName, null));
+        }
     }
 
     /**
--- a/src/share/classes/sun/security/tools/keytool/Resources.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/classes/sun/security/tools/keytool/Resources.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -65,10 +65,16 @@
         {"Generates.certificate.from.a.certificate.request",
                 "Generates certificate from a certificate request"}, //-gencert
         {"Generates.CRL", "Generates CRL"}, //-gencrl
+        {"Generated.keyAlgName.secret.key",
+                "Generated {0} secret key"}, //-genseckey
+        {"Generated.keysize.bit.keyAlgName.secret.key",
+                "Generated {0}-bit {1} secret key"}, //-genseckey
         {"Imports.entries.from.a.JDK.1.1.x.style.identity.database",
                 "Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb
         {"Imports.a.certificate.or.a.certificate.chain",
                 "Imports a certificate or a certificate chain"}, //-importcert
+        {"Imports.a.password",
+                "Imports a password"}, //-importpass
         {"Imports.one.or.all.entries.from.another.keystore",
                 "Imports one or all entries from another keystore"}, //-importkeystore
         {"Clones.a.key.entry",
@@ -220,6 +226,8 @@
         {"Must.specify.alias", "Must specify alias"},
         {"Keystore.password.must.be.at.least.6.characters",
                 "Keystore password must be at least 6 characters"},
+        {"Enter.the.password.to.be.stored.",
+                "Enter the password to be stored:  "},
         {"Enter.keystore.password.", "Enter keystore password:  "},
         {"Enter.source.keystore.password.", "Enter source keystore password:  "},
         {"Enter.destination.keystore.password.", "Enter destination keystore password:  "},
@@ -328,6 +336,7 @@
         {"New.prompt.", "New {0}: "},
         {"Passwords.must.differ", "Passwords must differ"},
         {"Re.enter.new.prompt.", "Re-enter new {0}: "},
+        {"Re.enter.passpword.", "Re-enter password: "},
         {"Re.enter.new.password.", "Re-enter new password: "},
         {"They.don.t.match.Try.again", "They don't match. Try again"},
         {"Enter.prompt.alias.name.", "Enter {0} alias name:  "},
--- a/src/share/demo/management/JTop/JTop.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/demo/management/JTop/JTop.java	Tue Oct 08 14:57:32 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -87,12 +87,36 @@
  */
 public class JTop extends JPanel {
 
+    private static class StatusBar extends JPanel {
+        private static final long serialVersionUID = -6483392381797633018L;
+        private final JLabel statusText;
+
+        public StatusBar(boolean defaultVisible) {
+            super(new GridLayout(1, 1));
+            statusText = new JLabel();
+            statusText.setVisible(defaultVisible);
+            add(statusText);
+        }
+
+        @Override
+        public Dimension getMaximumSize() {
+            Dimension maximum = super.getMaximumSize();
+            Dimension minimum = getMinimumSize();
+            return new Dimension(maximum.width, minimum.height);
+        }
+
+        public void setMessage(String text) {
+            statusText.setText(text);
+            statusText.setVisible(true);
+        }
+    }
     private static final long serialVersionUID = -1499762160973870696L;
     private MBeanServerConnection server;
     private ThreadMXBean tmbean;
     private MyTableModel tmodel;
+    private final StatusBar statusBar;
     public JTop() {
-        super(new GridLayout(1,0));
+        super(new GridBagLayout());
 
         tmodel = new MyTableModel();
         JTable table = new JTable(tmodel);
@@ -108,7 +132,22 @@
         JScrollPane scrollPane = new JScrollPane(table);
 
         // Add the scroll pane to this panel.
-        add(scrollPane);
+        GridBagConstraints c1 = new GridBagConstraints();
+        c1.fill = GridBagConstraints.BOTH;
+        c1.gridy = 0;
+        c1.gridx = 0;
+        c1.weightx = 1;
+        c1.weighty = 1;
+        add(scrollPane, c1);
+
+        statusBar = new StatusBar(false);
+        GridBagConstraints c2 = new GridBagConstraints();
+        c2.fill = GridBagConstraints.HORIZONTAL;
+        c2.gridy = 1;
+        c2.gridx = 0;
+        c2.weightx = 1.0;
+        c2.weighty = 0.0;
+        add(statusBar, c2);
     }
 
     // Set the MBeanServerConnection object for communicating
@@ -123,9 +162,13 @@
             e.printStackTrace();
         }
         if (!tmbean.isThreadCpuTimeSupported()) {
-            System.err.println("This VM does not support thread CPU time monitoring");
+            statusBar.setMessage("Monitored VM does not support thread CPU time measurement");
         } else {
-            tmbean.setThreadCpuTimeEnabled(true);
+            try {
+                tmbean.setThreadCpuTimeEnabled(true);
+            } catch (SecurityException e) {
+                statusBar.setMessage("Monitored VM does not have permission for enabling thread cpu time measurement");
+            }
         }
     }
 
--- a/src/share/javavm/export/jvm.h	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/javavm/export/jvm.h	Tue Oct 08 14:57:32 2013 -0700
@@ -472,6 +472,11 @@
 JNIEXPORT jbyteArray JNICALL
 JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls);
 
+JNIEXPORT jbyteArray JNICALL
+JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field);
+
+JNIEXPORT jbyteArray JNICALL
+JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method);
 
 /*
  * New (JDK 1.4) reflection implementation
--- a/src/share/lib/security/java.security-windows	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/lib/security/java.security-windows	Tue Oct 08 14:57:32 2013 -0700
@@ -127,7 +127,7 @@
 # This is a comma-separated list of algorithm and/or algorithm:provider
 # entries.
 #
-securerandom.strongAlgorithms=Windows-PRNG:SunMSCAPI
+securerandom.strongAlgorithms=Windows-PRNG:SunMSCAPI,SHA1PRNG:SUN
 
 #
 # Class to instantiate as the javax.security.auth.login.Configuration
--- a/src/share/native/java/lang/reflect/Executable.c	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/share/native/java/lang/reflect/Executable.c	Tue Oct 08 14:57:32 2013 -0700
@@ -23,11 +23,7 @@
  * questions.
  */
 
-#include <string.h>
-#include <stdlib.h>
-
 #include "jni.h"
-#include "jni_util.h"
 #include "jvm.h"
 #include "java_lang_reflect_Executable.h"
 
@@ -36,3 +32,9 @@
                                                  jobject method) {
   return JVM_GetMethodParameters(env, method);
 }
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_lang_reflect_Executable_getTypeAnnotationBytes0(JNIEnv *env,
+                                                          jobject method) {
+  return JVM_GetMethodTypeAnnotations(env, method);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/java/lang/reflect/Field.c	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#include "jni.h"
+#include "jvm.h"
+#include "java_lang_reflect_Field.h"
+
+JNIEXPORT jbyteArray JNICALL
+Java_java_lang_reflect_Field_getTypeAnnotationBytes0(JNIEnv *env,
+                                                     jobject field) {
+    return JVM_GetFieldTypeAnnotations(env, field);
+}
--- a/src/windows/bin/cmdtoargs.c	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/windows/bin/cmdtoargs.c	Tue Oct 08 14:57:32 2013 -0700
@@ -53,6 +53,16 @@
 static StdArg *stdargs;
 static int    stdargc;
 
+static int copyCh(USHORT ch, char* dest) {
+    if (HIBYTE(ch) == 0) {
+        *dest = (char)ch;
+        return 1;
+    } else {
+        *((USHORT *)dest) = ch;
+        return 2;
+    }
+}
+
 static char* next_arg(char* cmdline, char* arg, jboolean* wildcard) {
 
     char* src = cmdline;
@@ -61,31 +71,43 @@
     int quotes = 0;
     int slashes = 0;
 
-    char prev = 0;
-    char ch = 0;
+    // "prev"/"ch" may contain either a single byte, or a double byte
+    // character encoded in CP_ACP.
+    USHORT prev = 0;
+    USHORT ch = 0;
     int i;
     jboolean done = JNI_FALSE;
+    int charLength;
 
     *wildcard = JNI_FALSE;
-    while ((ch = *src) != 0 && !done) {
+    while (!done) {
+        charLength = CharNextExA(CP_ACP, src, 0) - src;
+        if (charLength == 0) {
+            break;
+        } else if (charLength == 1) {
+            ch = (USHORT)(UCHAR)src[0];
+        } else {
+            ch = ((USHORT *)src)[0];
+        }
+
         switch (ch) {
-        case '"':
+        case L'"':
             if (separator) {
                 done = JNI_TRUE;
                 break;
             }
-            if (prev == '\\') {
+            if (prev == L'\\') {
                 for (i = 1; i < slashes; i += 2) {
-                    *dest++ = prev;
+                    dest += copyCh(prev, dest);
                 }
                 if (slashes % 2 == 1) {
-                    *dest++ = ch;
+                    dest += copyCh(ch, dest);
                 } else {
                     quotes++;
                 }
-            } else if (prev == '"' && quotes % 2 == 0) {
+            } else if (prev == L'"' && quotes % 2 == 0) {
                 quotes++;
-                *dest++ = ch; // emit every other consecutive quote
+                dest += copyCh(ch, dest); // emit every other consecutive quote
             } else if (quotes == 0) {
                 quotes++; // starting quote
             } else {
@@ -94,7 +116,7 @@
             slashes = 0;
             break;
 
-        case '\\':
+        case L'\\':
             slashes++;
             if (separator) {
                 done = JNI_TRUE;
@@ -102,23 +124,23 @@
             }
             break;
 
-        case ' ':
-        case '\t':
-            if (prev == '\\') {
+        case L' ':
+        case L'\t':
+            if (prev == L'\\') {
                 for (i = 0 ; i < slashes; i++) {
-                   *dest++ = prev;
+                    dest += copyCh(prev, dest);
                 }
             }
             if (quotes % 2 == 1) {
-                *dest++ = ch;
+                dest += copyCh(ch, dest);
             } else {
                 separator = JNI_TRUE;
             }
             slashes = 0;
             break;
 
-        case '*':
-        case '?':
+        case L'*':
+        case L'?':
             if (separator) {
                 done = JNI_TRUE;
                 separator = JNI_FALSE;
@@ -127,36 +149,36 @@
             if (quotes % 2 == 0) {
                 *wildcard = JNI_TRUE;
             }
-            if (prev == '\\') {
+            if (prev == L'\\') {
                 for (i = 0 ; i < slashes ; i++) {
-                    *dest++ = prev;
+                    dest += copyCh(prev, dest);
                 }
             }
-            *dest++ = ch;
+            dest += copyCh(ch, dest);
             break;
 
         default:
-            if (prev == '\\') {
+            if (prev == L'\\') {
                 for (i = 0 ; i < slashes ; i++) {
-                   *dest++ = prev;
+                    dest += copyCh(prev, dest);
                 }
-                *dest++ = ch;
+                dest += copyCh(ch, dest);
             } else if (separator) {
                 done = JNI_TRUE;
             } else {
-                *dest++ = ch;
+                dest += copyCh(ch, dest);
             }
             slashes = 0;
         }
 
         if (!done) {
             prev = ch;
-            src++;
+            src += charLength;
         }
     }
-    if (prev == '\\') {
+    if (prev == L'\\') {
         for (i = 0; i < slashes; i++) {
-            *dest++ = prev;
+            dest += copyCh(prev, dest);
         }
     }
     *dest = 0;
--- a/src/windows/classes/java/net/PlainSocketImpl.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/windows/classes/java/net/PlainSocketImpl.java	Tue Oct 08 14:57:32 2013 -0700
@@ -191,14 +191,17 @@
     }
 
     protected synchronized void accept(SocketImpl s) throws IOException {
-        // pass in the real impl not the wrapper.
-        SocketImpl delegate = ((PlainSocketImpl)s).impl;
-        delegate.address = new InetAddress();
-        delegate.fd = new FileDescriptor();
-        impl.accept(delegate);
-
-        // set fd to delegate's fd to be compatible with older releases
-        s.fd = delegate.fd;
+        if (s instanceof PlainSocketImpl) {
+            // pass in the real impl not the wrapper.
+            SocketImpl delegate = ((PlainSocketImpl)s).impl;
+            delegate.address = new InetAddress();
+            delegate.fd = new FileDescriptor();
+            impl.accept(delegate);
+            // set fd to delegate's fd to be compatible with older releases
+            s.fd = delegate.fd;
+        } else {
+            impl.accept(s);
+        }
     }
 
     void setFileDescriptor(FileDescriptor fd) {
--- a/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/windows/classes/sun/security/mscapi/SunMSCAPI.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -56,7 +56,7 @@
     }
 
     public SunMSCAPI() {
-        super("SunMSCAPI", 1.7d, INFO);
+        super("SunMSCAPI", 1.8d, INFO);
 
         // if there is no security manager installed, put directly into
         // the provider. Otherwise, create a temporary map and use a
--- a/src/windows/demo/jvmti/hprof/hprof_md.c	Tue Oct 08 14:53:14 2013 -0700
+++ b/src/windows/demo/jvmti/hprof/hprof_md.c	Tue Oct 08 14:57:32 2013 -0700
@@ -82,9 +82,6 @@
     struct sockaddr_in s;
     int fd;
 
-    /* create a socket */
-    fd = (int)socket(AF_INET, SOCK_STREAM, 0);
-
     /* find remote host's addr from name */
     if ((hentry = gethostbyname(hostname)) == NULL) {
         return -1;
@@ -97,8 +94,15 @@
     s.sin_port = htons(port);
     s.sin_family = AF_INET;
 
+    /* create a socket */
+    fd = (int)socket(AF_INET, SOCK_STREAM, 0);
+    if (INVALID_SOCKET == fd) {
+        return 0;
+    }
+
     /* now try connecting */
-    if (-1 == connect(fd, (struct sockaddr*)&s, sizeof(s))) {
+    if (SOCKET_ERROR == connect(fd, (struct sockaddr*)&s, sizeof(s))) {
+        closesocket(fd);
         return 0;
     }
     return fd;
--- a/test/ProblemList.txt	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/ProblemList.txt	Tue Oct 08 14:57:32 2013 -0700
@@ -134,6 +134,9 @@
 # 8021230
 java/lang/ThreadLocal/ThreadLocalSupplierTest.java              generic-all
 
+# 8023201
+java/lang/instrument/RetransformBigClass.sh                     generic-all
+java/lang/instrument/RedefineBigClass.sh                        generic-all
 
 ############################################################################
 
@@ -163,9 +166,6 @@
 # 7027502
 demo/jvmti/hprof/MonitorTest.java                               generic-all
 
-# 8021186
-jdk/lambda/vm/DefaultMethodsTest.java                           generic-all 
-
 # 8024423 - JVMTI: GetLoadedClasses doesn't enumerate anonymous classes 
 demo/jvmti/hprof/HeapAllTest.java                               generic-all
 demo/jvmti/hprof/HeapBinaryFormatTest.java                      generic-all
@@ -322,6 +322,18 @@
 # 8007410
 tools/launcher/FXLauncherTest.java                              linux-all
 
+# 8025427
+sun/tools/jstat/jstatLineCounts1.sh                                 generic-all
+sun/tools/jstat/jstatLineCounts2.sh                                 generic-all
+sun/tools/jstat/jstatLineCounts3.sh                                 generic-all
+sun/tools/jstat/jstatTimeStamp1.sh                                  generic-all
+sun/tools/jstat/jstatGcCauseOutput1.sh                              generic-all
+sun/tools/jstat/jstatLineCounts4.sh                                 generic-all
+sun/tools/jstatd/jstatdDefaults.sh                                  generic-all
+sun/tools/jstatd/jstatdExternalRegistry.sh                          generic-all
+sun/tools/jstatd/jstatdPort.sh                                      generic-all
+sun/tools/jstatd/jstatdServerName.sh                                generic-all
+
 ############################################################################
 
 # jdk_jdi
--- a/test/java/io/File/createTempFile/SpecialTempFile.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/io/File/createTempFile/SpecialTempFile.java	Tue Oct 08 14:57:32 2013 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8013827 8011950 8017212
+ * @bug 8013827 8011950 8017212 8025128
  * @summary Check whether File.createTempFile can handle special parameters
  * @author Dan Xu
  */
@@ -33,7 +33,9 @@
 
 public class SpecialTempFile {
 
-    private static void test(String name, String[] prefix, String[] suffix) {
+    private static void test(String name, String[] prefix, String[] suffix,
+                             boolean exceptionExpected) throws IOException
+    {
         if (prefix == null || suffix == null
             || prefix.length != suffix.length)
         {
@@ -41,24 +43,38 @@
         }
 
         final String exceptionMsg = "Unable to create temporary file";
-        final String errMsg = "IOException is expected";
+        String[] dirs = { null, "." };
 
         for (int i = 0; i < prefix.length; i++) {
             boolean exceptionThrown = false;
             File f = null;
-            System.out.println("In test " + name
-                               + ", creating temp file with prefix, "
-                               + prefix[i] + ", suffix, " + suffix[i]);
-            try {
-                f = File.createTempFile(prefix[i], suffix[i]);
-            } catch (IOException e) {
-                if (exceptionMsg.equals(e.getMessage()))
-                    exceptionThrown = true;
-                else
-                    System.out.println("Wrong error message:" + e.getMessage());
+
+            for (String dir: dirs) {
+                System.out.println("In test " + name +
+                                   ", creating temp file with prefix, " +
+                                   prefix[i] + ", suffix, " + suffix[i] +
+                                   ", in dir, " + dir);
+
+                try {
+                    if (dir == null || dir.isEmpty())
+                        f = File.createTempFile(prefix[i], suffix[i]);
+                    else
+                        f = File.createTempFile(prefix[i], suffix[i], new File(dir));
+                } catch (IOException e) {
+                    if (exceptionExpected) {
+                        if (e.getMessage().startsWith(exceptionMsg))
+                            exceptionThrown = true;
+                        else
+                            System.out.println("Wrong error message:" +
+                                               e.getMessage());
+                    } else {
+                        throw e;
+                    }
+                }
+
+                if (exceptionExpected && (!exceptionThrown || f != null))
+                    throw new RuntimeException("IOException is expected");
             }
-            if (!exceptionThrown || f != null)
-                throw new RuntimeException(errMsg);
         }
     }
 
@@ -71,7 +87,17 @@
         }
         String[] nulPre = { name + "\u0000" };
         String[] nulSuf = { ".test" };
-        test("NulName", nulPre, nulSuf);
+        test("NulName", nulPre, nulSuf, true);
+
+        // Test JDK-8025128
+        String[] goodPre = { "///..///", "/foo" };
+        String[] goodSuf = { ".temp", ".tmp" };
+        test("goodName", goodPre, goodSuf, false);
+
+        // Test JDK-8011950
+        String[] slashPre = { "temp", "///..///", "/foo" };
+        String[] slashSuf = { "///..///..", "///..///..", "///..///.." };
+        test("SlashedName", slashPre, slashSuf, true);
 
         // Windows tests
         if (!System.getProperty("os.name").startsWith("Windows"))
@@ -80,11 +106,6 @@
         // Test JDK-8013827
         String[] resvPre = { "LPT1.package.zip", "com7.4.package.zip" };
         String[] resvSuf = { ".temp", ".temp" };
-        test("ReservedName", resvPre, resvSuf);
-
-        // Test JDK-8011950
-        String[] slashPre = { "///..///", "temp", "///..///" };
-        String[] slashSuf = { ".temp", "///..///..", "///..///.." };
-        test("SlashedName", slashPre, slashSuf);
+        test("ReservedName", resvPre, resvSuf, true);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/annotation/typeAnnotations/GetAnnotatedInterfaces.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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 8022324
+ * @summary Test Class.getAnnotatedInterfaces() returns 0-length array as
+ *          specified.
+ */
+
+import java.lang.reflect.AnnotatedType;
+import java.util.Arrays;
+
+public class GetAnnotatedInterfaces {
+    private static final Class<?>[] testData = {
+        GetAnnotatedInterfaces.class,
+        (new Clz() {}).getClass(),
+        (new Object() {}).getClass(),
+        Object[].class,
+        Object[][].class,
+        Object[][][].class,
+        Object.class,
+        void.class,
+        int.class,
+    };
+
+    private static int failed = 0;
+    private static int tests = 0;
+
+    public static void main(String[] args) throws Exception {
+        testReturnsZeroLengthArray();
+
+        if (failed != 0)
+            throw new RuntimeException("Test failed, check log for details");
+        if (tests != 9)
+            throw new RuntimeException("Not all cases ran, failing");
+    }
+
+    private static void testReturnsZeroLengthArray() {
+        for (Class<?> toTest : testData) {
+            tests++;
+
+            AnnotatedType[] res = toTest.getAnnotatedInterfaces();
+
+            if (res == null) {
+                failed++;
+                System.out.println(toTest + ".class.getAnnotatedInterface() returns" +
+                        "'null' should zero length array");
+            } else if (res.length != 0) {
+                failed++;
+                System.out.println(toTest + ".class.getAnnotatedInterfaces() returns: "
+                        + Arrays.asList(res) + ", should be a zero length array of AnnotatedType");
+            }
+        }
+    }
+
+    interface If {}
+
+    static abstract class Clz {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/annotation/typeAnnotations/GetAnnotatedReceiverType.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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 8024915
+ */
+
+import java.lang.reflect.AnnotatedType;
+import java.util.Arrays;
+
+public class GetAnnotatedReceiverType {
+    public void method() {}
+    public void method0(GetAnnotatedReceiverType this) {}
+    public static void method4() {}
+
+    class Inner0 {
+        public Inner0() {}
+    }
+
+    class Inner1 {
+        public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {}
+    }
+
+    private static int failures = 0;
+    private static int tests = 0;
+
+    public static void main(String[] args) throws NoSuchMethodException {
+        checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method").getAnnotatedReceiverType(),
+                "getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType");
+        checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(),
+                "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
+
+        checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0").getAnnotatedReceiverType(),
+                "getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType");
+        checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class).getAnnotatedReceiverType(),
+                "getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType");
+
+        checkNull(GetAnnotatedReceiverType.class.getMethod("method4").getAnnotatedReceiverType(),
+                "getAnnotatedReceiverType() on a static method should return null");
+
+        if (failures != 0)
+            throw new RuntimeException("Test failed, see log for details");
+        else if (tests != 5)
+            throw new RuntimeException("Not all cases ran, failing");
+    }
+
+    private static void checkNull(Object o, String msg) {
+        if (o != null) {
+            failures++;
+            System.err.println(msg);
+        }
+        tests++;
+    }
+
+    private static void checkEmptyAT(AnnotatedType a, String msg) {
+        if (a.getAnnotations().length != 0) {
+            failures++;
+            System.err.print(msg);
+        }
+        tests++;
+    }
+}
--- a/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/lang/annotation/typeAnnotations/GetAnnotatedSuperclass.java	Tue Oct 08 14:57:32 2013 -0700
@@ -23,12 +23,16 @@
 
 /*
  * @test
- * @bug 8022343
- * @summary make sure Class.getAnnotatedSuperclass() returns null when specified to do so
+ * @bug 8022343 8007072
+ * @summary Test Class.getAnnotatedSuperclass() returns null/non-null
+ *          AnnotatedType as specified
  */
 
+import java.lang.reflect.AnnotatedType;
+import java.util.Arrays;
+
 public class GetAnnotatedSuperclass {
-    private static final Class<?>[] testData = {
+    private static final Class<?>[] nullTestData = {
         Object.class,
         If.class,
         Object[].class,
@@ -36,9 +40,31 @@
         int.class,
     };
 
+    private static final Class<?>[] nonNullTestData = {
+        Class.class,
+        GetAnnotatedSuperclass.class,
+        (new If() {}).getClass(),
+        (new Clz() {}).getClass(),
+        (new Object() {}).getClass(),
+    };
+
+    private static int failed = 0;
+    private static int tests = 0;
+
     public static void main(String[] args) throws Exception {
-        int failed = 0;
-        for (Class<?> toTest : testData) {
+        testReturnsNull();
+        testReturnsEmptyAT();
+
+        if (failed != 0)
+            throw new RuntimeException("Test failed, check log for details");
+        if (tests != 10)
+            throw new RuntimeException("Not all cases ran, failing");
+    }
+
+    private static void testReturnsNull() {
+        for (Class<?> toTest : nullTestData) {
+            tests++;
+
             Object res = toTest.getAnnotatedSuperclass();
 
             if (res != null) {
@@ -47,10 +73,26 @@
                         + res + ", should be null");
             }
         }
+    }
 
-        if (failed != 0)
-            throw new RuntimeException("Test failed, check log for details");
+    private static void testReturnsEmptyAT() {
+        for (Class<?> toTest : nonNullTestData) {
+            tests++;
+
+            AnnotatedType res = toTest.getAnnotatedSuperclass();
+
+            if (res == null) {
+                failed++;
+                System.out.println(toTest + ".getAnnotatedSuperclass() returns 'null' should  be non-null");
+            } else if (res.getAnnotations().length != 0) {
+                failed++;
+                System.out.println(toTest + ".getAnnotatedSuperclass() returns: "
+                        + Arrays.asList(res.getAnnotations()) + ", should be an empty AnnotatedType");
+            }
+        }
     }
 
     interface If {}
+
+    static abstract class Clz {}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/8022701/BogoLoader.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,156 @@
+/*
+ * 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.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import jdk.internal.org.objectweb.asm.*;
+
+public class BogoLoader extends ClassLoader {
+
+    static interface VisitorMaker {
+    ClassVisitor make(ClassVisitor visitor);
+    }
+
+
+    /**
+     * Use this property to verify that the desired classloading is happening.
+     */
+    private final boolean verbose = Boolean.getBoolean("bogoloader.verbose");
+    /**
+     * Use this property to disable replacement for testing purposes.
+     */
+    private final boolean noReplace = Boolean.getBoolean("bogoloader.noreplace");
+
+    /**
+     * Set of class names that should be loaded with this loader.
+     * Others are loaded with the system class loader, except for those
+     * that are transformed.
+     */
+    private Set<String> nonSystem;
+
+    /**
+     * Map from class names to a bytecode transformer factory.
+     */
+    private Map<String, VisitorMaker> replaced;
+
+    /**
+     * Keep track (not terribly efficiently) of which classes have already
+     * been loaded by this class loader.
+     */
+    private final Vector<String> history = new Vector<String>();
+
+    private boolean useSystemLoader(String name) {
+        return ! nonSystem.contains(name) && ! replaced.containsKey(name);
+    }
+
+    public BogoLoader(Set<String> non_system, Map<String, VisitorMaker> replaced) {
+        super(Thread.currentThread().getContextClassLoader());
+        this.nonSystem = non_system;
+        this.replaced = replaced;
+    }
+
+    private byte[] readResource(String className) throws IOException {
+        return readResource(className, "class");
+    }
+
+    private byte[] readResource(String className, String suffix) throws IOException {
+        // Note to the unwary -- "/" works on Windows, leave it alone.
+        String fileName = className.replace('.', '/') + "." + suffix;
+        InputStream origStream = getResourceAsStream(fileName);
+        if (origStream == null) {
+            throw new IOException("Resource not found : " + fileName);
+        }
+        BufferedInputStream stream = new java.io.BufferedInputStream(origStream);
+        byte[] data = new byte[stream.available()];
+        int how_many = stream.read(data);
+        // Really ought to deal with the corner cases of stream.available()
+        return data;
+    }
+
+    protected byte[] getClass(String name) throws ClassNotFoundException,
+    IOException {
+        return readResource(name, "class");
+    }
+
+    /**
+     * Loads the named class from the system class loader unless
+     * the name appears in either replaced or nonSystem.
+     * nonSystem classes are loaded into this classloader,
+     * and replaced classes get their content from the specified array
+     * of bytes (and are also loaded into this classloader).
+     */
+    protected Class<?> loadClass(String name, boolean resolve)
+            throws ClassNotFoundException {
+        Class<?> clazz;
+
+        if (history.contains(name)) {
+            Class<?> c = this.findLoadedClass(name);
+            return c;
+        }
+        if (useSystemLoader(name)) {
+            clazz = findSystemClass(name);
+            if (verbose) System.err.println("Loading system class " + name);
+        } else {
+            history.add(name);
+            try {
+                if (verbose) {
+                    System.err.println("Loading classloader class " + name);
+                }
+                byte[] classData = getClass(name);;
+                boolean expanded = false;
+                if (!noReplace && replaced.containsKey(name)) {
+                    if (verbose) {
+                        System.err.println("Replacing class " + name);
+                    }
+                    ClassReader cr = new ClassReader(classData);
+                    ClassWriter cw = new ClassWriter(0);
+                    VisitorMaker vm = replaced.get(name);
+                    cr.accept(vm.make(cw), 0);
+                    classData = cw.toByteArray();
+                }
+                clazz = defineClass(name, classData, 0, classData.length);
+            } catch (java.io.EOFException ioe) {
+                throw new ClassNotFoundException(
+                        "IO Exception in reading class : " + name + " ", ioe);
+            } catch (ClassFormatError ioe) {
+                throw new ClassNotFoundException(
+                        "ClassFormatError in reading class file: ", ioe);
+            } catch (IOException ioe) {
+                throw new ClassNotFoundException(
+                        "IO Exception in reading class file: ", ioe);
+            }
+        }
+        if (clazz == null) {
+            throw new ClassNotFoundException(name);
+        }
+        if (resolve) {
+            resolveClass(clazz);
+        }
+        return clazz;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/8022701/InvokeSeveralWays.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.
+ *
+ */
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Tries various ways of ultimately invoking MethodSupplier.m(),
+ * except that m has been made inaccessible and some exception should be
+ * thrown instead.
+ */
+public class InvokeSeveralWays {
+    public static int test(String args[], Class expected) throws Exception {
+        int failures = 0;
+        try {
+            Class.forName("Invoker").getMethod("invoke").invoke(null);
+            System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier");
+            failures++;
+        } catch (InvocationTargetException e) {
+            Throwable c = e.getCause();
+            if (expected.isInstance(c))
+               System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
+            else {
+               failures++;
+               System.out.println("FAIL: Unexpected wrapped exception " + c);
+               e.printStackTrace(System.out);
+            }
+        } catch (Throwable e) {
+            failures++;
+            System.out.println("FAIL: Unexpected exception has been caught " + e);
+            e.printStackTrace(System.out);
+        }
+        System.out.println();
+        try {
+            Class.forName("Invoker").getMethod("invoke2").invoke(null);
+            System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier");
+            failures++;
+        } catch (InvocationTargetException e) {
+            Throwable c = e.getCause();
+            if (expected.isInstance(c))
+               System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
+            else {
+               failures++;
+               System.out.println("FAIL: Unexpected wrapped exception " + c);
+               e.printStackTrace(System.out);
+            }
+        } catch (Throwable e) {
+            failures++;
+            System.out.println("FAIL: Unexpected exception has been caught " + e);
+            e.printStackTrace(System.out);
+        }
+        System.out.println();
+        try {
+            Invoker.invoke();
+            System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier");
+            failures++;
+        } catch (Throwable e) {
+            if (expected.isInstance(e))
+               System.out.println("EXPECTED: " + expected.getName() + ", "+ e);
+            else {
+            failures++;
+            System.out.println("FAIL: Unexpected exception has been caught " + e);
+            e.printStackTrace(System.out);
+            }
+        }
+        System.out.println();
+        try {
+            Invoker.invoke2();
+            System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier");
+            failures++;
+         } catch (Throwable e) {
+            if (expected.isInstance(e))
+               System.out.println("EXPECTED: " + expected.getName() + ", "+ e);
+            else {
+                failures++;
+                System.out.println("FAIL: Unexpected exception has been caught " + e);
+                e.printStackTrace(System.out);
+            }
+        }
+        System.out.println();
+        if (failures > 0) {
+          System.out.println("Saw " + failures + " failures");
+        }
+        return failures;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/8022701/Invoker.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.
+ *
+ */
+
+public class Invoker {
+    /**
+     * Use a method handle to invoke m.
+     */
+    public static void invoke() {
+        MyFunctionalInterface fi = null;
+        fi = new MethodSupplier()::<Integer, String, Long>m;
+        fi.invokeMethodReference();
+    }
+    /**
+     * Invoke m directly.
+     */
+    public static void invoke2() {
+        MethodSupplier ms = new MethodSupplier();
+        ms.m();
+    }
+}
+
+interface MyFunctionalInterface {
+       void invokeMethodReference();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/8022701/MHIllegalAccess.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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 8022701
+ * @summary Illegal access exceptions via methodhandle invocations threw wrong error.
+ *
+ * @compile -XDignore.symbol.file BogoLoader.java InvokeSeveralWays.java MHIllegalAccess.java MethodSupplier.java
+ * @run main/othervm MHIllegalAccess
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.HashSet;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+public class MHIllegalAccess implements Opcodes {
+
+   public static void main(String args[]) throws Throwable  {
+      System.out.println("Classpath is " + System.getProperty("java.class.path"));
+      System.out.println();
+
+      /**
+       * Make method m be private to provoke an IllegalAccessError.
+       */
+      BogoLoader.VisitorMaker privatize = new BogoLoader.VisitorMaker() {
+           public ClassVisitor make(ClassVisitor cv) {
+               return new ClassVisitor(Opcodes.ASM5, cv) {
+                   public MethodVisitor visitMethod(int access, String name, String desc,
+                           String signature, String[] exceptions) {
+                       if (name.equals("m"))
+                           access = (access | ACC_PRIVATE) & ~ (ACC_PUBLIC | ACC_PROTECTED);
+                           return super.visitMethod(access, name, desc, signature, exceptions);
+                   }
+               };
+           }
+       };
+
+     /**
+       * Rename method m as nemo to provoke a NoSuchMethodError.
+       */
+     BogoLoader.VisitorMaker changeName = new BogoLoader.VisitorMaker() {
+           public ClassVisitor make(ClassVisitor cv) {
+               return new ClassVisitor(Opcodes.ASM5, cv) {
+                   public MethodVisitor visitMethod(int access, String name, String desc,
+                           String signature, String[] exceptions) {
+                       if (name.equals("m"))
+                           name = "nemo";
+                           return super.visitMethod(access, name, desc, signature, exceptions);
+                   }
+               };
+           }
+       };
+
+      int failures = 0;
+      failures += testOneError(privatize, args, IllegalAccessError.class);
+      failures += testOneError(changeName, args, NoSuchMethodError.class);
+      if (failures > 0) {
+          System.out.println("Saw " + failures + " failures, see standard out for details");
+          throw new Error("FAIL test");
+      }
+   }
+
+   /**
+    *
+    * @param vm VisitorMaker, to be stored in a table and passed to a BogoLoader
+    * @param args A copy of the main args, to be passed on to InvokeSeveralWays.test
+    * @param expected The class of the exception that should be thrown after
+    *                 attempted invocation of MethodSupplier.m.
+    * @throws ClassNotFoundException
+    * @throws Throwable
+    */
+    private static int testOneError(BogoLoader.VisitorMaker vm, String[] args, Class expected) throws ClassNotFoundException, Throwable {
+      HashMap<String, BogoLoader.VisitorMaker> replace = new HashMap<String, BogoLoader.VisitorMaker>();
+      replace.put("MethodSupplier", vm);
+
+      HashSet<String> in_bogus = new HashSet<String>();
+        in_bogus.add("InvokeSeveralWays");
+        in_bogus.add("MyFunctionalInterface");
+        in_bogus.add("Invoker");
+
+        BogoLoader bl = new BogoLoader(in_bogus, replace);
+        Class<?> isw = bl.loadClass("InvokeSeveralWays");
+        Object[] arg_for_args = new Object[2];
+        arg_for_args[0] = args;
+        arg_for_args[1] = expected;
+        try {
+            Object result = isw.getMethod("test", String[].class, Class.class).invoke(null, arg_for_args);
+            return (Integer)result;
+        } catch (InvocationTargetException e) {
+            Throwable th = e.getCause();
+            throw th == null ? e : th;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/8022701/MethodSupplier.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ * Note: this class is only used in this form to facilitate compilation of the
+ * rest of the code.  Before execution, the bytecodes are mutilated in a
+ * BogoLoader to either make m be private or have a different name.
+ */
+
+public class MethodSupplier {
+    public void m() {
+        System.out.println("good");
+    }
+}
+
--- a/test/java/lang/invoke/AccessControlTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/lang/invoke/AccessControlTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -133,7 +133,7 @@
         }
 
         /** Simulate all assertions from the spec. for Lookup.in:
-         * <hr/>
+         * <hr>
          * Creates a lookup on the specified new lookup class.
          * [A1] The resulting object will report the specified
          * class as its own {@link #lookupClass lookupClass}.
@@ -155,7 +155,7 @@
          * </ul>
          * Other than the above cases, the new lookup will have the same
          * access capabilities as the original. [A8]
-         * <hr/>
+         * <hr>
          */
         public LookupCase in(Class<?> c2) {
             Class<?> c1 = lookupClass();
--- a/test/java/lang/invoke/BigArityTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/lang/invoke/BigArityTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -93,6 +93,65 @@
     }
 
     @Test
+    public void asCollectorIAE01() throws ReflectiveOperationException {
+        final int [] INVALID_ARRAY_LENGTHS = {
+            Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -2, -1, 255, 256, Integer.MAX_VALUE - 1, Integer.MAX_VALUE
+        };
+        MethodHandle target = MethodHandles.publicLookup().findStatic(Arrays.class,
+                "deepToString", MethodType.methodType(String.class, Object[].class));
+        int minbig = Integer.MAX_VALUE;
+        for (int invalidLength : INVALID_ARRAY_LENGTHS) {
+            if (minbig > invalidLength && invalidLength > 100)  minbig = invalidLength;
+            try {
+                target.asCollector(Object[].class, invalidLength);
+                assert(false) : invalidLength;
+            } catch (IllegalArgumentException ex) {
+                System.out.println("OK: "+ex);
+            }
+        }
+        // Sizes not in the above array are good:
+        target.asCollector(Object[].class, minbig-1);
+        for (int i = 2; i <= 10; i++)
+            target.asCollector(Object[].class, minbig-i);
+    }
+
+    @Test
+    public void invoker02() {
+        for (int i = 0; i < 255; i++) {
+            MethodType mt = MethodType.genericMethodType(i);
+            MethodType expMT = mt.insertParameterTypes(0, MethodHandle.class);
+            if (i < 254) {
+                assertEquals(expMT, MethodHandles.invoker(mt).type());
+            } else {
+                try {
+                    MethodHandles.invoker(mt);
+                    assert(false) : i;
+                } catch (IllegalArgumentException ex) {
+                    System.out.println("OK: "+ex);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void exactInvoker02() {
+        for (int i = 0; i < 255; i++) {
+            MethodType mt = MethodType.genericMethodType(i);
+            MethodType expMT = mt.insertParameterTypes(0, MethodHandle.class);
+            if (i < 254) {
+                assertEquals(expMT, MethodHandles.exactInvoker(mt).type());
+            } else {
+                try {
+                    MethodHandles.exactInvoker(mt);
+                    assert(false) : i;
+                } catch (IllegalArgumentException ex) {
+                    System.out.println("OK: "+ex);
+                }
+            }
+        }
+    }
+
+    @Test
     public void testBoundaryValues() throws Throwable {
         for (int badArity : new int[]{ -1, MAX_JVM_ARITY+1, MAX_JVM_ARITY }) {
             try {
@@ -102,6 +161,37 @@
                 System.out.println("OK: "+ex);
             }
         }
+        final int MAX_MH_ARITY      = MAX_JVM_ARITY - 1;  // mh.invoke(arg*[N])
+        final int MAX_INVOKER_ARITY = MAX_MH_ARITY - 1;   // inv.invoke(mh, arg*[N])
+        for (int arity : new int[]{ 0, 1, MAX_MH_ARITY-2, MAX_MH_ARITY-1, MAX_MH_ARITY }) {
+            MethodHandle mh = MH_hashArguments(arity);
+            if (arity < MAX_INVOKER_ARITY) {
+                MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
+                MethodHandle gimh = MethodHandles.invoker(mh.type());
+                MethodHandle simh = MethodHandles.spreadInvoker(mh.type(), 0);
+                if (arity != 0) {
+                    simh = MethodHandles.spreadInvoker(mh.type(), 1);
+                } else {
+                    try {
+                        simh = MethodHandles.spreadInvoker(mh.type(), 1);
+                        assert(false) : arity;
+                    } catch (IllegalArgumentException ex) {
+                        System.out.println("OK: "+ex);
+                    }
+                }
+                if (arity != 0) {
+                    simh = MethodHandles.spreadInvoker(mh.type(), arity-1);
+                } else {
+                    try {
+                        simh = MethodHandles.spreadInvoker(mh.type(), arity-1);
+                        assert(false) : arity;
+                    } catch (IllegalArgumentException ex) {
+                        System.out.println("OK: "+ex);
+                    }
+                }
+                simh = MethodHandles.spreadInvoker(mh.type(), arity);
+            }
+        }
     }
 
     // Make sure the basic argument spreading and varargs mechanisms are working.
@@ -133,7 +223,7 @@
             if (cls == Object[].class)
                 r = smh.invokeExact(tail);
             else if (cls == Integer[].class)
-                r = smh.invokeExact((Integer[]) tail);
+                r = smh.invokeExact((Integer[]) tail); //warning OK, see 8019340
             else
                 r = smh.invoke(tail);
             assertEquals(r0, r);
@@ -235,21 +325,41 @@
             MethodHandle mh_VA = mh.asSpreader(cls, arity);
             assert(mh_VA.type().parameterType(0) == cls);
             testArities(cls, arity, iterations, verbose, mh, mh_VA);
+            // mh_CA will collect arguments of a particular type and pass them to mh_VA
+            MethodHandle mh_CA = mh_VA.asCollector(cls, arity);
+            MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity);
+            assert(mh_CA.type().equals(mh.type()));
+            assert(mh_VA2.type().equals(mh_VA.type()));
             if (cls != Object[].class) {
-                // mh_CA will collect arguments of a particular type and pass them to mh_VA
-                MethodHandle mh_CA = mh_VA.asCollector(cls, arity);
-                MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity);
                 try {
                     mh_VA2.invokeWithArguments(new Object[arity]);
                     throw new AssertionError("should not reach");
                 } catch (ClassCastException | WrongMethodTypeException ex) {
                 }
-                assert(mh_CA.type().equals(mh.type()));
-                assert(mh_VA2.type().equals(mh_VA.type()));
-                testArities(cls, arity, iterations, false, mh_CA, mh_VA2);
             }
+            int iterations_VA = iterations / 100;
+            testArities(cls, arity, iterations_VA, false, mh_CA, mh_VA2);
         }
     }
+
+   /**
+     * Tests calls to {@link BigArityTest#hashArguments hashArguments} as related to a single given arity N.
+     * Applies the given {@code mh} to a set of N integer arguments, checking the answer.
+     * Also applies the varargs variation {@code mh_VA} to an array of type C[] (given by {@code cls}).
+     * Test steps:
+     * <ul>
+     * <li>mh_VA.invokeExact(new C[]{ arg, ... })</li>
+     * <li>mh.invokeWithArguments((Object[]) new C[]{ arg, ... })</li>
+     * <li>exactInvoker(mh.type()).invokeWithArguments(new Object[]{ mh, arg, ... })</li>
+     * <li>invoker(mh.type()).invokeWithArguments(new Object[]{ mh, arg, ... })</li>
+     * </ul>
+     * @param cls     array type for varargs call (one of Object[], Number[], Integer[], Comparable[])
+     * @param arity   N, the number of arguments to {@code mh} and length of its varargs array, in [0..255]
+     * @param iterations  number of times to repeat each test step (at least 4)
+     * @param verbose are we printing extra output?
+     * @param mh      a fixed-arity version of {@code hashArguments}
+     * @param mh_VA   a variable-arity version of {@code hashArguments}, accepting the given array type {@code cls}
+     */
     private void testArities(Class<? extends Object[]> cls,
                              int arity,
                              int iterations,
@@ -292,7 +402,7 @@
             if (cls == Object[].class)
                 r = mh_VA.invokeExact(args);
             else if (cls == Integer[].class)
-                r = mh_VA.invokeExact((Integer[])args);
+                r = mh_VA.invokeExact((Integer[])args); //warning OK, see 8019340
             else
                 r = mh_VA.invoke(args);
             assertEquals(r0, r);
@@ -392,10 +502,16 @@
     a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
     a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
     // </editor-fold>
-    a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB]); // hashArguments_252
         assertEquals(r0, r);
         MethodType mt = MethodType.genericMethodType(ARITY);
         MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+        test252(mh, a, r0);
+        MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY);
+        test252(mh_CA, a, r0);
+    }
+    public void test252(MethodHandle mh, Object[] a, Object r0) throws Throwable {
+        Object r;
         r = mh.invokeExact(
     // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
     a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
@@ -599,10 +715,16 @@
     a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
     a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
     // </editor-fold>
-    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]); // hashArguments_253
         assertEquals(r0, r);
         MethodType mt = MethodType.genericMethodType(ARITY);
         MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+        test253(mh, a, r0);
+        MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY);
+        test253(mh_CA, a, r0);
+    }
+    public void test253(MethodHandle mh, Object[] a, Object r0) throws Throwable {
+        Object r;
         r = mh.invokeExact(
     // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
     a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
@@ -648,7 +770,6 @@
     // </editor-fold>
     a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
         assertEquals(r0, r);
-        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
         r = ximh.invokeWithArguments(cat(mh,a));
         assertEquals(r0, r);
         MethodHandle gimh = MethodHandles.invoker(mh.type());
@@ -674,7 +795,6 @@
     // </editor-fold>
     a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
         assertEquals(r0, r);
-        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
         r = gimh.invokeWithArguments(cat(mh,a));
         assertEquals(r0, r);
         mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
@@ -808,10 +928,16 @@
     a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
     a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
     // </editor-fold>
-    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]); // hashArguments_254
         assertEquals(r0, r);
         MethodType mt = MethodType.genericMethodType(ARITY);
         MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+        test254(mh, a, r0);
+        MethodHandle mh_CA = MH_hashArguments_VA.asFixedArity().asCollector(Object[].class, ARITY);
+        test254(mh_CA, a, r0);
+    }
+    public void test254(MethodHandle mh, Object[] a, Object r0) throws Throwable {
+        Object r;
         r = mh.invokeExact(
     // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
     a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
@@ -833,7 +959,6 @@
     // </editor-fold>
     a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
         assertEquals(r0, r);
-        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
         r = mh.invokeWithArguments(a);
         assertEquals(r0, r);
         try {
@@ -998,7 +1123,7 @@
     a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
     a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
     // </editor-fold>
-    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]);
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]); // hashArguments_255
         assertEquals(r0, r);
         MethodType mt = MethodType.genericMethodType(ARITY);
         MethodHandle mh;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/CallStaticInitOrder.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,275 @@
+/*
+ * 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 static initializer invocation order
+ *
+ * @build indify.Indify
+ * @compile CallStaticInitOrder.java
+ * @run main/othervm
+ *      indify.Indify
+ *      --expand-properties --classpath ${test.classes}
+ *      --java test.java.lang.invoke.CallStaticInitOrder
+ */
+
+package test.java.lang.invoke;
+
+import java.io.*;
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class CallStaticInitOrder {
+    private static int TICK;
+    private static synchronized int tick(String event) {
+        int n = ++TICK;
+        System.out.println("event #"+n+" = "+event);
+        return n;
+    }
+
+    static int Init1Tick;
+    private static class Init1 {
+        static { Init1Tick = tick("foo -> Init1.<clinit>"); }
+        static int foo() { return Init1Tick; }
+    }
+
+    static int Init2Tick;
+    private static class Init2 {
+        static { Init2Tick = tick("bar -> Init2.<clinit>"); }
+        static int bar() { return Init2Tick; }
+    }
+
+    static int Init3Tick;
+    private static class Init3 {
+        static { Init3Tick = tick("baz -> Init3.<clinit>"); }
+        static int baz() { return Init3Tick; }
+    }
+
+    static int Init4Tick;
+    private static class Init4 {
+        static { Init4Tick = tick("bat -> Init4.<clinit>"); }
+        static int bat() { return Init4Tick; }
+    }
+
+    static int Init5Tick;
+    private static class Init5 {
+        static { Init5Tick = tick("read bang -> Init5.<clinit>"); }
+        static int bang = Init5Tick;
+    }
+
+    static int Init6Tick;
+    private static class Init6 {
+        static { Init6Tick = tick("write pong -> Init6.<clinit>"); }
+        static int pong;
+    }
+
+    private static final MutableCallSite CONSTANT_CS_baz;
+    private static MethodHandle MH_foo() throws ReflectiveOperationException {
+        return lookup().findStatic(Init1.class, "foo", methodType(int.class));
+    }
+    private static final MethodHandle CONSTANT_MH_bar;
+    private static MethodHandle MH_baz() throws ReflectiveOperationException {
+        return lookup().findStatic(Init3.class, "baz", methodType(int.class));
+    }
+    private static final MethodHandle CONSTANT_MH_bat;
+    private static final MethodHandle CONSTANT_MH_bangGetter;
+    private static final MethodHandle CONSTANT_MH_pongSetter;
+    static {
+        try {
+            int t1 = tick("CallStaticInitOrder.<clinit>");
+            {
+                CONSTANT_CS_baz = new MutableCallSite(methodType(int.class));
+                // MH_foo() := lookup().findStatic(Init1.class, "foo", methodType(int.class));
+                CONSTANT_MH_bar = lookup().findStatic(Init2.class, "bar", methodType(int.class));
+                // MH_baz() := lookup().findStatic(Init3.class, "baz", methodType(int.class));
+                CONSTANT_MH_bat = lookup().unreflect(Init4.class.getDeclaredMethod("bat"));
+                CONSTANT_MH_bangGetter = lookup().findStaticGetter(Init5.class, "bang", int.class);
+                MethodHandle pongSetter = lookup().findStaticSetter(Init6.class, "pong", int.class);
+                MethodHandle tickGetter = lookup().findStaticGetter(CallStaticInitOrder.class, "Init6Tick", int.class);
+                CONSTANT_MH_pongSetter = filterReturnValue(insertArguments(pongSetter, 0, -99), tickGetter);
+            }
+            int t2 = tick("CallStaticInitOrder.<clinit> done");
+            assertEquals(t1+1, t2);  // no ticks in between
+        } catch (Exception ex) {
+            throw new InternalError(ex.toString());
+        }
+    }
+
+    public static void main(String... av) throws Throwable {
+        testInit();
+        if (LAST_LOSER != null)  throw LAST_LOSER;
+    }
+
+    private static Throwable LAST_LOSER;
+
+    private static void assertEquals(int expected, int actual) {
+        if (expected != actual) {
+            Throwable loser = new AssertionError("expected: " + expected + ", actual: " + actual);
+            if (LAST_LOSER != null)
+                LAST_LOSER.printStackTrace(System.out);
+            LAST_LOSER = loser;
+        }
+    }
+
+    private static void testInit() throws Throwable {
+        System.out.println("runFoo = "+runFoo());
+        System.out.println("runBar = "+runBar());
+        try {
+            runBaz();
+        } catch (IllegalStateException ex) {
+            tick("runBaz throw/catch");
+        }
+        CONSTANT_CS_baz.setTarget(MH_baz());
+        System.out.println("runBaz = "+runBaz());
+        System.out.println("runBat = "+runBat());
+        System.out.println("runBang = "+runBang());
+        System.out.println("runPong = "+runPong());
+    }
+
+    private static int runFoo() throws Throwable {
+        assertEquals(Init1Tick, 0);  // Init1 not initialized yet
+        int t1 = tick("runFoo");
+        int t2 = (int) INDY_foo().invokeExact();
+        int t3 = tick("runFoo done");
+        assertEquals(Init1Tick, t2);  // when Init1 was initialized
+        assertEquals(t1+2, t3);  // exactly two ticks in between
+        assertEquals(t1+1, t2);  // init happened inside
+        return t2;
+    }
+    private static MethodHandle INDY_foo() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm().invoke(lookup(), "foo", methodType(int.class))).dynamicInvoker();
+    }
+
+    private static int runBar() throws Throwable {
+        assertEquals(Init2Tick, 0);  // Init2 not initialized yet
+        int t1 = tick("runBar");
+        int t2 = (int) INDY_bar().invokeExact();
+        int t3 = tick("runBar done");
+        assertEquals(Init2Tick, t2);  // when Init2 was initialized
+        assertEquals(t1+2, t3);  // exactly two ticks in between
+        assertEquals(t1+1, t2);  // init happened inside
+        return t2;
+    }
+    private static MethodHandle INDY_bar() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm().invoke(lookup(), "bar", methodType(int.class))).dynamicInvoker();
+    }
+
+    private static int runBaz() throws Throwable {
+        assertEquals(Init3Tick, 0);  // Init3 not initialized yet
+        int t1 = tick("runBaz");
+        int t2 = (int) INDY_baz().invokeExact();
+        int t3 = tick("runBaz done");
+        assertEquals(Init3Tick, t2);  // when Init3 was initialized
+        assertEquals(t1+2, t3);  // exactly two ticks in between
+        assertEquals(t1+1, t2);  // init happened inside
+        return t2;
+    }
+    private static MethodHandle INDY_baz() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm().invoke(lookup(), "baz", methodType(int.class))).dynamicInvoker();
+    }
+
+    private static int runBat() throws Throwable {
+        assertEquals(Init4Tick, 0);  // Init4 not initialized yet
+        int t1 = tick("runBat");
+        int t2 = (int) INDY_bat().invokeExact();
+        int t3 = tick("runBat done");
+        assertEquals(Init4Tick, t2);  // when Init4 was initialized
+        assertEquals(t1+2, t3);  // exactly two ticks in between
+        assertEquals(t1+1, t2);  // init happened inside
+        return t2;
+    }
+    private static MethodHandle INDY_bat() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm().invoke(lookup(), "bat", methodType(int.class))).dynamicInvoker();
+    }
+
+    private static int runBang() throws Throwable {
+        assertEquals(Init5Tick, 0);  // Init5 not initialized yet
+        int t1 = tick("runBang");
+        int t2 = (int) INDY_bang().invokeExact();
+        int t3 = tick("runBang done");
+        assertEquals(Init5Tick, t2);  // when Init5 was initialized
+        assertEquals(t1+2, t3);  // exactly two ticks in between
+        assertEquals(t1+1, t2);  // init happened inside
+        return t2;
+    }
+    private static MethodHandle INDY_bang() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm().invoke(lookup(), "bang", methodType(int.class))).dynamicInvoker();
+    }
+
+    private static int runPong() throws Throwable {
+        assertEquals(Init6Tick, 0);  // Init6 not initialized yet
+        int t1 = tick("runPong");
+        int t2 = (int) INDY_pong().invokeExact();
+        int t3 = tick("runPong done");
+        assertEquals(Init6Tick, t2);  // when Init6 was initialized
+        assertEquals(t1+2, t3);  // exactly two ticks in between
+        assertEquals(t1+1, t2);  // init happened inside
+        return t2;
+    }
+    private static MethodHandle INDY_pong() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm().invoke(lookup(), "pong", methodType(int.class))).dynamicInvoker();
+    }
+
+    private static CallSite bsm(Lookup caller, String name, MethodType type) throws ReflectiveOperationException {
+        System.out.println("bsm "+name+type);
+        CallSite res;
+        switch (name) {
+        case "foo":
+            res = new ConstantCallSite(MH_foo()); break;
+        case "bar":
+            res = new ConstantCallSite(CONSTANT_MH_bar); break;
+        case "baz":
+            res = CONSTANT_CS_baz; break;
+        case "bat":
+            res = new ConstantCallSite(CONSTANT_MH_bat); break;
+        case "bang":
+            res = new ConstantCallSite(CONSTANT_MH_bangGetter); break;
+        case "pong":
+            res = new ConstantCallSite(CONSTANT_MH_pongSetter); break;
+        default:
+            res = null;
+        }
+        if (res == null || !res.type().equals(type)) {
+            throw new AssertionError(String.valueOf(res));
+        }
+        return res;
+    }
+    private static MethodHandle MH_bsm() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return lookup().findStatic(lookup().lookupClass(), "bsm",
+                                   methodType(CallSite.class, Lookup.class, String.class, MethodType.class));
+    }
+    private static void shouldNotCallThis() {
+        // if this gets called, the transformation has not taken place
+        throw new AssertionError("this code should be statically transformed away by Indify");
+    }
+}
--- a/test/java/lang/invoke/JavaDocExamplesTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/lang/invoke/JavaDocExamplesTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -53,7 +53,11 @@
     }
 
     public void run() throws Throwable {
+        testMisc();
+        testFindStatic();
+        testFindConstructor();
         testFindVirtual();
+        testFindSpecial();
         testPermuteArguments();
         testDropArguments();
         testFilterArguments();
@@ -99,7 +103,8 @@
 
 {}
 
-    @Test public void testFindVirtual() throws Throwable {
+    @Test public void testMisc() throws Throwable {
+// Extra tests, not from javadoc:
 {}
 MethodHandle CONCAT_3 = LOOKUP.findVirtual(String.class,
   "concat", methodType(String.class, String.class));
@@ -114,6 +119,92 @@
 {}
     }
 
+    @Test public void testFindStatic() throws Throwable {
+{}
+MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
+  "asList", methodType(List.class, Object[].class));
+assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
+{}
+    }
+
+    @Test public void testFindVirtual() throws Throwable {
+{}
+MethodHandle MH_concat = publicLookup().findVirtual(String.class,
+  "concat", methodType(String.class, String.class));
+MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
+  "hashCode", methodType(int.class));
+MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
+  "hashCode", methodType(int.class));
+assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
+assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
+assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
+// interface method:
+MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
+  "subSequence", methodType(CharSequence.class, int.class, int.class));
+assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
+// constructor "internal method" must be accessed differently:
+MethodType MT_newString = methodType(void.class); //()V for new String()
+try { assertEquals("impossible", lookup()
+        .findVirtual(String.class, "<init>", MT_newString));
+ } catch (NoSuchMethodException ex) { } // OK
+MethodHandle MH_newString = publicLookup()
+  .findConstructor(String.class, MT_newString);
+assertEquals("", (String) MH_newString.invokeExact());
+{}
+    }
+
+    @Test public void testFindConstructor() throws Throwable {
+{}
+MethodHandle MH_newArrayList = publicLookup().findConstructor(
+  ArrayList.class, methodType(void.class, Collection.class));
+Collection orig = Arrays.asList("x", "y");
+Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
+assert(orig != copy);
+assertEquals(orig, copy);
+// a variable-arity constructor:
+MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
+  ProcessBuilder.class, methodType(void.class, String[].class));
+ProcessBuilder pb = (ProcessBuilder)
+  MH_newProcessBuilder.invoke("x", "y", "z");
+assertEquals("[x, y, z]", pb.command().toString());
+{}
+    }
+
+// for testFindSpecial
+{}
+static class Listie extends ArrayList {
+  public String toString() { return "[wee Listie]"; }
+  static Lookup lookup() { return MethodHandles.lookup(); }
+}
+{}
+
+    @Test public void testFindSpecial() throws Throwable {
+{}
+// no access to constructor via invokeSpecial:
+MethodHandle MH_newListie = Listie.lookup()
+  .findConstructor(Listie.class, methodType(void.class));
+Listie l = (Listie) MH_newListie.invokeExact();
+try { assertEquals("impossible", Listie.lookup().findSpecial(
+        Listie.class, "<init>", methodType(void.class), Listie.class));
+ } catch (NoSuchMethodException ex) { } // OK
+// access to super and self methods via invokeSpecial:
+MethodHandle MH_super = Listie.lookup().findSpecial(
+  ArrayList.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_this = Listie.lookup().findSpecial(
+  Listie.class, "toString" , methodType(String.class), Listie.class);
+MethodHandle MH_duper = Listie.lookup().findSpecial(
+  Object.class, "toString" , methodType(String.class), Listie.class);
+assertEquals("[]", (String) MH_super.invokeExact(l));
+assertEquals(""+l, (String) MH_this.invokeExact(l));
+assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
+try { assertEquals("inaccessible", Listie.lookup().findSpecial(
+        String.class, "toString", methodType(String.class), Listie.class));
+ } catch (IllegalAccessException ex) { } // OK
+Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
+assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
+{}
+    }
+
     @Test public void testPermuteArguments() throws Throwable {
         {{
 {} /// JAVADOC
@@ -190,6 +281,28 @@
             }}
     }
 
+    @Test public void testCollectArguments() throws Throwable {
+        {{
+{} /// JAVADOC
+MethodHandle deepToString = publicLookup()
+  .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
+MethodHandle ts1 = deepToString.asCollector(String[].class, 1);
+assertEquals("[strange]", (String) ts1.invokeExact("strange"));
+MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
+assertEquals("[up, down]", (String) ts2.invokeExact("up", "down"));
+MethodHandle ts3 = deepToString.asCollector(String[].class, 3);
+MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2);
+assertEquals("[top, [up, down], strange]",
+             (String) ts3_ts2.invokeExact("top", "up", "down", "strange"));
+MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1);
+assertEquals("[top, [up, down], [strange]]",
+             (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange"));
+MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
+assertEquals("[top, [[up, down, strange], charm], bottom]",
+             (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
+            }}
+    }
+
     @Test public void testFoldArguments() throws Throwable {
         {{
 {} /// JAVADOC
@@ -264,6 +377,12 @@
 MethodHandle eq2 = equals.asSpreader(Object[].class, 2);
 assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" }));
 assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" }));
+// try to spread from anything but a 2-array:
+for (int n = 0; n <= 10; n++) {
+  Object[] badArityArgs = (n == 2 ? null : new Object[n]);
+  try { assert((boolean) eq2.invokeExact(badArityArgs) && false); }
+  catch (IllegalArgumentException ex) { } // OK
+}
 // spread both arguments from a String array:
 MethodHandle eq2s = equals.asSpreader(String[].class, 2);
 assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" }));
--- a/test/java/lang/invoke/MethodHandlesTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/lang/invoke/MethodHandlesTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -140,7 +140,7 @@
         Object actual   = calledLog.get(calledLog.size() - 1);
         if (expected.equals(actual) && verbosity < 9)  return;
         System.out.println("assertCalled "+name+":");
-        System.out.println("expected:   "+expected);
+        System.out.println("expected:   "+deepToString(expected));
         System.out.println("actual:     "+actual);
         System.out.println("ex. types:  "+getClasses(expected));
         System.out.println("act. types: "+getClasses(actual));
@@ -148,7 +148,25 @@
     }
     static void printCalled(MethodHandle target, String name, Object... args) {
         if (verbosity >= 3)
-            System.out.println("calling MH="+target+" to "+name+Arrays.toString(args));
+            System.out.println("calling MH="+target+" to "+name+deepToString(args));
+    }
+    static String deepToString(Object x) {
+        if (x == null)  return "null";
+        if (x instanceof Collection)
+            x = ((Collection)x).toArray();
+        if (x instanceof Object[]) {
+            Object[] ax = (Object[]) x;
+            ax = Arrays.copyOf(ax, ax.length, Object[].class);
+            for (int i = 0; i < ax.length; i++)
+                ax[i] = deepToString(ax[i]);
+            x = Arrays.deepToString(ax);
+        }
+        if (x.getClass().isArray())
+            try {
+                x = Arrays.class.getMethod("toString", x.getClass()).invoke(null, x);
+            } catch (ReflectiveOperationException ex) { throw new Error(ex); }
+        assert(!(x instanceof Object[]));
+        return x.toString();
     }
 
     static Object castToWrapper(Object value, Class<?> dst) {
@@ -230,6 +248,12 @@
                     { param = c; break; }
             }
         }
+        if (param.isArray()) {
+            Class<?> ctype = param.getComponentType();
+            Object arg = Array.newInstance(ctype, 2);
+            Array.set(arg, 0, randomArg(ctype));
+            return arg;
+        }
         if (param.isInterface() && param.isAssignableFrom(List.class))
             return Arrays.asList("#"+nextArg());
         if (param.isInterface() || param.isAssignableFrom(String.class))
@@ -253,6 +277,9 @@
             args[i] = randomArg(param);
         return args;
     }
+    static Object[] randomArgs(List<Class<?>> params) {
+        return randomArgs(params.toArray(new Class<?>[params.size()]));
+    }
 
     @SafeVarargs @SuppressWarnings("varargs")
     static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
@@ -323,6 +350,11 @@
         }
         return list.asType(listType);
     }
+    /** Variation of varargsList, but with the given ptypes and rtype. */
+    static MethodHandle varargsList(List<Class<?>> ptypes, Class<?> rtype) {
+        MethodHandle list = varargsList(ptypes.size(), rtype);
+        return list.asType(MethodType.methodType(rtype, ptypes));
+    }
     private static MethodHandle LIST_TO_STRING, LIST_TO_INT;
     private static String listToString(List<?> x) { return x.toString(); }
     private static int listToInt(List<?> x) { return x.toString().hashCode(); }
@@ -363,6 +395,7 @@
         protected Example(String name) { this.name = name; }
         @SuppressWarnings("LeakingThisInConstructor")
         protected Example(int x) { this(); called("protected <init>", this, x); }
+        //Example(Void x) { does not exist; lookup elicts NoSuchMethodException }
         @Override public String toString() { return name; }
 
         public void            v0()     { called("v0", this); }
@@ -463,6 +496,9 @@
         return lookup.in(defc);
     }
 
+    /** Is findVirtual (etc.) of "&lt;init&lt;" supposed to elicit a NoSuchMethodException? */
+    final static boolean INIT_REF_CAUSES_NSME = true;
+
     @Test
     public void testFindStatic() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
@@ -483,6 +519,8 @@
         testFindStatic(Example.class, Object.class, "s7", float.class, double.class);
 
         testFindStatic(false, PRIVATE, Example.class, void.class, "bogus");
+        testFindStatic(false, PRIVATE, Example.class, void.class, "<init>", int.class);
+        testFindStatic(false, PRIVATE, Example.class, void.class, "<init>", Void.class);
         testFindStatic(false, PRIVATE, Example.class, void.class, "v0");
     }
 
@@ -505,11 +543,12 @@
             target = maybeMoveIn(lookup, defc).findStatic(defc, methodName, type);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            assertExceptionClass(
+                (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
+                ?   NoSuchMethodException.class
+                :   IllegalAccessException.class,
+                noAccess);
             if (verbosity >= 5)  ex.printStackTrace(System.out);
-            if (name.contains("bogus"))
-                assertTrue(noAccess instanceof NoSuchMethodException);
-            else
-                assertTrue(noAccess instanceof IllegalAccessException);
         }
         if (verbosity >= 3)
             System.out.println("findStatic "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target
@@ -527,6 +566,13 @@
             System.out.print(':');
     }
 
+    static void assertExceptionClass(Class<? extends Throwable> expected,
+                                     Throwable actual) {
+        if (expected.isInstance(actual))  return;
+        actual.printStackTrace();
+        assertEquals(expected, actual.getClass());
+    }
+
     static final boolean DEBUG_METHOD_HANDLE_NAMES = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
 
     // rough check of name string
@@ -556,6 +602,8 @@
         testFindVirtual(PubExample.class, void.class, "Pub/pro_v0");
 
         testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "bogus");
+        testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "<init>", int.class);
+        testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "<init>", Void.class);
         testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "s0");
 
         // test dispatch
@@ -568,6 +616,16 @@
         testFindVirtual(IntExample.Impl.class, IntExample.class, void.class, "Int/v0");
     }
 
+    @Test
+    public void testFindVirtualClone() throws Throwable {
+        // test some ad hoc system methods
+        testFindVirtual(false, PUBLIC, Object.class, Object.class, "clone");
+        testFindVirtual(true, PUBLIC, Object[].class, Object.class, "clone");
+        testFindVirtual(true, PUBLIC, int[].class, Object.class, "clone");
+        for (Class<?> cls : new Class<?>[]{ boolean[].class, long[].class, float[].class, char[].class })
+            testFindVirtual(true, PUBLIC, cls, Object.class, "clone");
+    }
+
     void testFindVirtual(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
         Class<?> rcvc = defc;
         testFindVirtual(rcvc, defc, ret, name, params);
@@ -580,6 +638,9 @@
     void testFindVirtual(Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
         testFindVirtual(true, lookup, rcvc, defc, ret, name, params);
     }
+    void testFindVirtual(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
+        testFindVirtual(positive, lookup, defc, defc, ret, name, params);
+    }
     void testFindVirtual(boolean positive, Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
         countTest(positive);
         String methodName = name.substring(1 + name.indexOf('/'));  // foo/bar => foo
@@ -591,11 +652,12 @@
             target = maybeMoveIn(lookup, defc).findVirtual(defc, methodName, type);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            assertExceptionClass(
+                (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
+                ?   NoSuchMethodException.class
+                :   IllegalAccessException.class,
+                noAccess);
             if (verbosity >= 5)  ex.printStackTrace(System.out);
-            if (name.contains("bogus"))
-                assertTrue(noAccess instanceof NoSuchMethodException);
-            else
-                assertTrue(noAccess instanceof IllegalAccessException);
         }
         if (verbosity >= 3)
             System.out.println("findVirtual "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target
@@ -618,8 +680,21 @@
         Object[] argsWithSelf = randomArgs(paramsWithSelf);
         if (selfc.isAssignableFrom(rcvc) && rcvc != selfc)  argsWithSelf[0] = randomArg(rcvc);
         printCalled(target, name, argsWithSelf);
-        target.invokeWithArguments(argsWithSelf);
-        assertCalled(name, argsWithSelf);
+        Object res = target.invokeWithArguments(argsWithSelf);
+        if (Example.class.isAssignableFrom(defc) || IntExample.class.isAssignableFrom(defc)) {
+            assertCalled(name, argsWithSelf);
+        } else if (name.equals("clone")) {
+            // Ad hoc method call outside Example.  For Object[].clone.
+            printCalled(target, name, argsWithSelf);
+            assertEquals(MethodType.methodType(Object.class, rcvc), target.type());
+            Object orig = argsWithSelf[0];
+            assertEquals(orig.getClass(), res.getClass());
+            if (res instanceof Object[])
+                assertArrayEquals((Object[])res, (Object[])argsWithSelf[0]);
+            assert(Arrays.deepEquals(new Object[]{res}, new Object[]{argsWithSelf[0]}));
+        } else {
+            assert(false) : Arrays.asList(positive, lookup, rcvc, defc, ret, name, deepToString(params));
+        }
         if (verbosity >= 1)
             System.out.print(':');
     }
@@ -632,11 +707,11 @@
         testFindSpecial(SubExample.class, Example.class, void.class, "pkg_v0");
         testFindSpecial(RemoteExample.class, PubExample.class, void.class, "Pub/pro_v0");
         // Do some negative testing:
-        testFindSpecial(false, EXAMPLE, SubExample.class, Example.class, void.class, "bogus");
-        testFindSpecial(false, PRIVATE, SubExample.class, Example.class, void.class, "bogus");
         for (Lookup lookup : new Lookup[]{ PRIVATE, EXAMPLE, PACKAGE, PUBLIC }) {
             testFindSpecial(false, lookup, Object.class, Example.class, void.class, "v0");
+            testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "bogus");
             testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", int.class);
+            testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", Void.class);
             testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "s0");
         }
     }
@@ -662,19 +737,25 @@
         countTest(positive);
         String methodName = name.substring(1 + name.indexOf('/'));  // foo/bar => foo
         MethodType type = MethodType.methodType(ret, params);
+        Lookup specialLookup = maybeMoveIn(lookup, specialCaller);
+        boolean specialAccessOK = (specialLookup.lookupClass() == specialCaller &&
+                                   (specialLookup.lookupModes() & Lookup.PRIVATE) != 0);
         MethodHandle target = null;
         Exception noAccess = null;
         try {
             if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
-            if (verbosity >= 5)  System.out.println("  lookup => "+maybeMoveIn(lookup, specialCaller));
-            target = maybeMoveIn(lookup, specialCaller).findSpecial(defc, methodName, type, specialCaller);
+            if (verbosity >= 5)  System.out.println("  lookup => "+specialLookup);
+            target = specialLookup.findSpecial(defc, methodName, type, specialCaller);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            assertExceptionClass(
+                (!specialAccessOK)  // this check should happen first
+                ?   IllegalAccessException.class
+                : (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
+                ?   NoSuchMethodException.class
+                : IllegalAccessException.class,
+                noAccess);
             if (verbosity >= 5)  ex.printStackTrace(System.out);
-            if (name.contains("bogus"))
-                assertTrue(noAccess instanceof NoSuchMethodException);
-            else
-                assertTrue(noAccess instanceof IllegalAccessException);
         }
         if (verbosity >= 3)
             System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target
@@ -719,7 +800,7 @@
             target = lookup.findConstructor(defc, type);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
-            assertTrue(noAccess instanceof IllegalAccessException);
+            assertTrue(noAccess.getClass().getName(), noAccess instanceof IllegalAccessException);
         }
         if (verbosity >= 3)
             System.out.println("findConstructor "+defc.getName()+".<init>/"+type+" => "+target
@@ -750,6 +831,8 @@
         testBind(Example.class, Object.class, "v2", int.class, Object.class);
         testBind(Example.class, Object.class, "v2", int.class, int.class);
         testBind(false, PRIVATE, Example.class, void.class, "bogus");
+        testBind(false, PRIVATE, Example.class, void.class, "<init>", int.class);
+        testBind(false, PRIVATE, Example.class, void.class, "<init>", Void.class);
         testBind(SubExample.class, void.class, "Sub/v0");
         testBind(SubExample.class, void.class, "Sub/pkg_v0");
         testBind(IntExample.Impl.class, void.class, "Int/v0");
@@ -773,11 +856,12 @@
             target = maybeMoveIn(lookup, defc).bind(receiver, methodName, type);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            assertExceptionClass(
+                (name.contains("bogus") || INIT_REF_CAUSES_NSME && name.contains("<init>"))
+                ?   NoSuchMethodException.class
+                :   IllegalAccessException.class,
+                noAccess);
             if (verbosity >= 5)  ex.printStackTrace(System.out);
-            if (name.contains("bogus"))
-                assertTrue(noAccess instanceof NoSuchMethodException);
-            else
-                assertTrue(noAccess instanceof IllegalAccessException);
         }
         if (verbosity >= 3)
             System.out.println("bind "+receiver+"."+name+"/"+type+" => "+target
@@ -840,6 +924,10 @@
         countTest(positive);
         String methodName = name.substring(1 + name.indexOf('/'));  // foo/bar => foo
         MethodType type = MethodType.methodType(ret, params);
+        Lookup specialLookup = (specialCaller != null ? maybeMoveIn(lookup, specialCaller) : null);
+        boolean specialAccessOK = (specialCaller != null &&
+                                   specialLookup.lookupClass() == specialCaller &&
+                                   (specialLookup.lookupModes() & Lookup.PRIVATE) != 0);
         Method rmethod = defc.getDeclaredMethod(methodName, params);
         MethodHandle target = null;
         Exception noAccess = null;
@@ -848,16 +936,15 @@
         try {
             if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
             if (isSpecial)
-                target = maybeMoveIn(lookup, specialCaller).unreflectSpecial(rmethod, specialCaller);
+                target = specialLookup.unreflectSpecial(rmethod, specialCaller);
             else
                 target = maybeMoveIn(lookup, defc).unreflect(rmethod);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            assertExceptionClass(
+                IllegalAccessException.class,  // NSME is impossible, since it was already reflected
+                noAccess);
             if (verbosity >= 5)  ex.printStackTrace(System.out);
-            if (name.contains("bogus"))
-                assertTrue(noAccess instanceof NoSuchMethodException);
-            else
-                assertTrue(noAccess instanceof IllegalAccessException);
         }
         if (verbosity >= 3)
             System.out.println("unreflect"+(isSpecial?"Special":"")+" "+defc.getName()+"."+name+"/"+type
@@ -1091,11 +1178,12 @@
         } catch (ReflectiveOperationException ex) {
             mh = null;
             noAccess = ex;
+            assertExceptionClass(
+                (fname.contains("bogus"))
+                ?   NoSuchFieldException.class
+                :   IllegalAccessException.class,
+                noAccess);
             if (verbosity >= 5)  ex.printStackTrace(System.out);
-            if (fname.contains("bogus"))
-                assertTrue(noAccess instanceof NoSuchFieldException);
-            else
-                assertTrue(noAccess instanceof IllegalAccessException);
         }
         if (verbosity >= 3)
             System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
@@ -1753,24 +1841,24 @@
     }
 
     @Test  // SLOW
-    public void testCollectArguments() throws Throwable {
+    public void testAsCollector() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
-        startTest("collectArguments");
+        startTest("asCollector");
         for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {
             if (verbosity >= 3)
-                System.out.println("collectArguments "+argType);
+                System.out.println("asCollector "+argType);
             for (int nargs = 0; nargs < 50; nargs++) {
                 if (CAN_TEST_LIGHTLY && nargs > 11)  break;
                 for (int pos = 0; pos <= nargs; pos++) {
                     if (CAN_TEST_LIGHTLY && pos > 2 && pos < nargs-2)  continue;
                     if (nargs > 10 && pos > 4 && pos < nargs-4 && pos % 10 != 3)
                         continue;
-                    testCollectArguments(argType, pos, nargs);
+                    testAsCollector(argType, pos, nargs);
                 }
             }
         }
     }
-    public void testCollectArguments(Class<?> argType, int pos, int nargs) throws Throwable {
+    public void testAsCollector(Class<?> argType, int pos, int nargs) throws Throwable {
         countTest();
         // fake up a MH with the same type as the desired adapter:
         MethodHandle fake = varargsArray(nargs);
@@ -1917,37 +2005,108 @@
     }
 
     @Test
+    public void testCollectArguments() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
+        startTest("collectArguments");
+        testFoldOrCollectArguments(true);
+    }
+
+    @Test
     public void testFoldArguments() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("foldArguments");
-        for (int nargs = 0; nargs <= 4; nargs++) {
-            for (int fold = 0; fold <= nargs; fold++) {
-                for (int pos = 0; pos <= nargs; pos++) {
-                    testFoldArguments(nargs, pos, fold);
+        testFoldOrCollectArguments(false);
+    }
+
+    void testFoldOrCollectArguments(boolean isCollect) throws Throwable {
+        for (Class<?> lastType : new Class<?>[]{ Object.class, String.class, int.class }) {
+            for (Class<?> collectType : new Class<?>[]{ Object.class, String.class, int.class, void.class }) {
+                int maxArity = 10;
+                if (collectType != String.class)  maxArity = 5;
+                if (lastType != Object.class)  maxArity = 4;
+                for (int nargs = 0; nargs <= maxArity; nargs++) {
+                    ArrayList<Class<?>> argTypes = new ArrayList<>(Collections.nCopies(nargs, Object.class));
+                    int maxMix = 20;
+                    if (collectType != Object.class)  maxMix = 0;
+                    Map<Object,Integer> argTypesSeen = new HashMap<>();
+                    for (int mix = 0; mix <= maxMix; mix++) {
+                        if (!mixArgs(argTypes, mix, argTypesSeen))  continue;
+                        for (int collect = 0; collect <= nargs; collect++) {
+                            for (int pos = 0; pos <= nargs - collect; pos++) {
+                                testFoldOrCollectArguments(argTypes, pos, collect, collectType, lastType, isCollect);
+                            }
+                        }
+                    }
                 }
             }
         }
     }
 
-    void testFoldArguments(int nargs, int pos, int fold) throws Throwable {
-        if (pos != 0)  return;  // can fold only at pos=0 for now
+    boolean mixArgs(List<Class<?>> argTypes, int mix, Map<Object,Integer> argTypesSeen) {
+        assert(mix >= 0);
+        if (mix == 0)  return true;  // no change
+        if ((mix >>> argTypes.size()) != 0)  return false;
+        for (int i = 0; i < argTypes.size(); i++) {
+            if (i >= 31)  break;
+            boolean bit = (mix & (1 << i)) != 0;
+            if (bit) {
+                Class<?> type = argTypes.get(i);
+                if (type == Object.class)
+                    type = String.class;
+                else if (type == String.class)
+                    type = int.class;
+                else
+                    type = Object.class;
+                argTypes.set(i, type);
+            }
+        }
+        Integer prev = argTypesSeen.put(new ArrayList<>(argTypes), mix);
+        if (prev != null) {
+            if (verbosity >= 4)  System.out.println("mix "+prev+" repeated "+mix+": "+argTypes);
+            return false;
+        }
+        if (verbosity >= 3)  System.out.println("mix "+mix+" = "+argTypes);
+        return true;
+    }
+
+    void testFoldOrCollectArguments(List<Class<?>> argTypes,  // argument types minus the inserted combineType
+                                    int pos, int fold, // position and length of the folded arguments
+                                    Class<?> combineType, // type returned from the combiner
+                                    Class<?> lastType,  // type returned from the target
+                                    boolean isCollect) throws Throwable {
+        int nargs = argTypes.size();
+        if (pos != 0 && !isCollect)  return;  // can fold only at pos=0 for now
         countTest();
-        MethodHandle target = varargsList(1 + nargs);
-        MethodHandle combine = varargsList(fold).asType(MethodType.genericMethodType(fold));
-        List<Object> argsToPass = Arrays.asList(randomArgs(nargs, Object.class));
+        List<Class<?>> combineArgTypes = argTypes.subList(pos, pos + fold);
+        List<Class<?>> targetArgTypes = new ArrayList<>(argTypes);
+        if (isCollect)  // does targret see arg[pos..pos+cc-1]?
+            targetArgTypes.subList(pos, pos + fold).clear();
+        if (combineType != void.class)
+            targetArgTypes.add(pos, combineType);
+        MethodHandle target = varargsList(targetArgTypes, lastType);
+        MethodHandle combine = varargsList(combineArgTypes, combineType);
+        List<Object> argsToPass = Arrays.asList(randomArgs(argTypes));
         if (verbosity >= 3)
-            System.out.println("fold "+target+" with "+combine);
-        MethodHandle target2 = MethodHandles.foldArguments(target, combine);
+            System.out.println((isCollect ? "collect" : "fold")+" "+target+" with "+combine);
+        MethodHandle target2;
+        if (isCollect)
+            target2 = MethodHandles.collectArguments(target, pos, combine);
+        else
+            target2 = MethodHandles.foldArguments(target, combine);
         // Simulate expected effect of combiner on arglist:
-        List<Object> expected = new ArrayList<>(argsToPass);
-        List<Object> argsToFold = expected.subList(pos, pos + fold);
+        List<Object> expectedList = new ArrayList<>(argsToPass);
+        List<Object> argsToFold = expectedList.subList(pos, pos + fold);
         if (verbosity >= 3)
-            System.out.println("fold: "+argsToFold+" into "+target2);
+            System.out.println((isCollect ? "collect" : "fold")+": "+argsToFold+" into "+target2);
         Object foldedArgs = combine.invokeWithArguments(argsToFold);
-        argsToFold.add(0, foldedArgs);
+        if (isCollect)
+            argsToFold.clear();
+        if (combineType != void.class)
+            argsToFold.add(0, foldedArgs);
         Object result = target2.invokeWithArguments(argsToPass);
         if (verbosity >= 3)
             System.out.println("result: "+result);
+        Object expected = target.invokeWithArguments(expectedList);
         if (!expected.equals(result))
             System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result+" != "+expected);
         assertEquals(expected, result);
--- a/test/java/lang/invoke/RevealDirectTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/lang/invoke/RevealDirectTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -104,6 +104,9 @@
         private static Lookup localLookup() { return lookup(); }
         private static List<Member> members() { return getMembers(lookup().lookupClass()); };
     }
+    static class Nestmate {
+        private static Lookup localLookup() { return lookup(); }
+    }
 
     static boolean VERBOSE = false;
 
@@ -152,7 +155,10 @@
                                   getMembers(Method.class, "invoke"));
         mems = callerSensitive(true, publicOnly(mems));
         // CS methods cannot be looked up with publicLookup
-        testOnMembersNoLookup("testCallerSensitiveNegative", mems, publicLookup());
+        testOnMembersNoLookup("testCallerSensitiveNegative/1", mems, publicLookup());
+        // CS methods have to be revealed with a matching lookupClass
+        testOnMembersNoReveal("testCallerSensitiveNegative/2", mems, Simple.localLookup(), publicLookup());
+        testOnMembersNoReveal("testCallerSensitiveNegative/3", mems, Simple.localLookup(), Nestmate.localLookup());
     }
     @Test public void testMethodHandleNatives() throws Throwable {
         if (VERBOSE)  System.out.println("@Test testMethodHandleNatives");
@@ -703,7 +709,7 @@
             try {
                 info = revLookup.revealDirect(mh);
                 if (expectEx2)  throw new AssertionError("unexpected revelation for negative test");
-            } catch (Throwable ex2) {
+            } catch (IllegalArgumentException|SecurityException ex2) {
                 if (VERBOSE)  System.out.println("  "+variation+": "+res+" => "+mh.getClass().getName()+" => (EX2)"+ex2);
                 if (expectEx2)
                     continue;  // this is OK; we expected the reflect to fail
--- a/test/java/lang/invoke/TestPrivateMember.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/lang/invoke/TestPrivateMember.java	Tue Oct 08 14:57:32 2013 -0700
@@ -47,7 +47,10 @@
         MethodHandles.Lookup lookup = MethodHandles.lookup();
         MethodType mt = MethodType.methodType(void.class);
         try {
-            MethodHandle mh = lookup.findStatic(Class.class, "checkInitted", mt);
+            Class<?> checkInittedHolder = TestPrivateMemberPackageSibling.class;
+            // Original model:  checkInittedHolder = Class.class;
+            // Not using Class.checkInitted because it could change without notice.
+            MethodHandle mh = lookup.findStatic(checkInittedHolder, "checkInitted", mt);
             throw new RuntimeException("IllegalAccessException not thrown");
         } catch (IllegalAccessException e) {
             // okay
@@ -55,3 +58,7 @@
         }
     }
 }
+
+class TestPrivateMemberPackageSibling {
+    private static void checkInitted() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/reflect/Parameter/BadClassFiles.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,462 @@
+/*
+ * 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
+ * @run main BadClassFiles
+ * @summary The reflection API should throw the correct exceptions.
+ */
+import java.lang.Class;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.MalformedParametersException;
+import java.lang.ClassLoader;
+import java.lang.ClassNotFoundException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class BadClassFiles {
+    private int errors = 0;
+
+
+    /* Class files were created by compiling the following source and
+     * then editing it:
+     *
+     * public class EmptyName {
+     *     public void m(int a, int b) {}
+     * }
+     *
+     */
+    private static final byte[] EmptyName_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,0,1,
+        0,1,98,1,0,10,83,111,
+        117,114,99,101,70,105,108,101,
+        1,0,14,69,109,112,116,121,
+        78,97,109,101,46,106,97,118,
+        97,12,0,4,0,5,1,0,
+        9,69,109,112,116,121,78,97,
+        109,101,1,0,16,106,97,118,
+        97,47,108,97,110,103,47,79,
+        98,106,101,99,116,0,33,0,
+        2,0,3,0,0,0,0,0,
+        2,0,1,0,4,0,5,0,
+        1,0,6,0,0,0,29,0,
+        1,0,1,0,0,0,5,42,
+        -73,0,1,-79,0,0,0,1,
+        0,7,0,0,0,6,0,1,
+        0,0,0,1,0,1,0,8,
+        0,9,0,2,0,6,0,0,
+        0,25,0,0,0,3,0,0,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,2,0,10,0,0,0,
+        9,2,0,11,0,0,0,12,
+        0,0,0,1,0,13,0,0,
+        0,2,0,14
+    };
+
+    private static final byte[] BadModifiers_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,97,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,17,66,97,100,77,
+        111,100,105,102,105,101,114,115,
+        46,106,97,118,97,12,0,4,
+        0,5,1,0,12,66,97,100,
+        77,111,100,105,102,105,101,114,
+        115,1,0,16,106,97,118,97,
+        47,108,97,110,103,47,79,98,
+        106,101,99,116,0,33,0,2,
+        0,3,0,0,0,0,0,2,
+        0,1,0,4,0,5,0,1,
+        0,6,0,0,0,29,0,1,
+        0,1,0,0,0,5,42,-73,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,1,0,1,0,8,0,
+        9,0,2,0,6,0,0,0,
+        25,0,0,0,3,0,0,0,
+        1,-79,0,0,0,1,0,7,
+        0,0,0,6,0,1,0,0,
+        0,2,0,10,0,0,0,9,
+        2,0,11,0,51,51,12,0,
+        0,0,1,0,13,0,0,0,
+        2,0,14
+    };
+
+    private static final byte[] BadNameIndex_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,97,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,17,66,97,100,78,
+        97,109,101,73,110,100,101,120,
+        46,106,97,118,97,12,0,4,
+        0,5,1,0,12,66,97,100,
+        78,97,109,101,73,110,100,101,
+        120,1,0,16,106,97,118,97,
+        47,108,97,110,103,47,79,98,
+        106,101,99,116,0,33,0,2,
+        0,3,0,0,0,0,0,2,
+        0,1,0,4,0,5,0,1,
+        0,6,0,0,0,29,0,1,
+        0,1,0,0,0,5,42,-73,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,1,0,1,0,8,0,
+        9,0,2,0,6,0,0,0,
+        25,0,0,0,3,0,0,0,
+        1,-79,0,0,0,1,0,7,
+        0,0,0,6,0,1,0,0,
+        0,2,0,10,0,0,0,9,
+        2,0,1,0,0,0,12,0,
+        0,0,1,0,13,0,0,0,
+        2,0,14
+    };
+
+    private static final byte[] NameIndexOutOfBounds_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,97,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,25,78,97,109,101,
+        73,110,100,101,120,79,117,116,
+        79,102,66,111,117,110,100,115,
+        46,106,97,118,97,12,0,4,
+        0,5,1,0,20,78,97,109,
+        101,73,110,100,101,120,79,117,
+        116,79,102,66,111,117,110,100,
+        115,1,0,16,106,97,118,97,
+        47,108,97,110,103,47,79,98,
+        106,101,99,116,0,33,0,2,
+        0,3,0,0,0,0,0,2,
+        0,1,0,4,0,5,0,1,
+        0,6,0,0,0,29,0,1,
+        0,1,0,0,0,5,42,-73,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,1,0,1,0,8,0,
+        9,0,2,0,6,0,0,0,
+        25,0,0,0,3,0,0,0,
+        1,-79,0,0,0,1,0,7,
+        0,0,0,6,0,1,0,0,
+        0,2,0,10,0,0,0,9,
+        2,0,-1,0,0,0,12,0,
+        0,0,1,0,13,0,0,0,
+        2,0,14
+
+    };
+
+    private static final byte[] ExtraParams_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,97,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,16,69,120,116,114,
+        97,80,97,114,97,109,115,46,
+        106,97,118,97,12,0,4,0,
+        5,1,0,11,69,120,116,114,
+        97,80,97,114,97,109,115,1,
+        0,16,106,97,118,97,47,108,
+        97,110,103,47,79,98,106,101,
+        99,116,0,33,0,2,0,3,
+        0,0,0,0,0,2,0,1,
+        0,4,0,5,0,1,0,6,
+        0,0,0,29,0,1,0,1,
+        0,0,0,5,42,-73,0,1,
+        -79,0,0,0,1,0,7,0,
+        0,0,6,0,1,0,0,0,
+        1,0,1,0,8,0,9,0,
+        2,0,6,0,0,0,25,0,
+        0,0,3,0,0,0,1,-79,
+        0,0,0,1,0,7,0,0,
+        0,6,0,1,0,0,0,2,
+        0,10,0,0,0,13,3,0,
+        11,0,0,0,12,0,0,0,
+        11,0,0,0,1,0,13,0,
+        0,0,2,0,14
+    };
+
+    private static final byte[] BadName1_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,46,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,13,66,97,100,78,
+        97,109,101,49,46,106,97,118,
+        97,12,0,4,0,5,1,0,
+        8,66,97,100,78,97,109,101,
+        49,1,0,16,106,97,118,97,
+        47,108,97,110,103,47,79,98,
+        106,101,99,116,0,33,0,2,
+        0,3,0,0,0,0,0,2,
+        0,1,0,4,0,5,0,1,
+        0,6,0,0,0,29,0,1,
+        0,1,0,0,0,5,42,-73,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,1,0,1,0,8,0,
+        9,0,2,0,6,0,0,0,
+        25,0,0,0,3,0,0,0,
+        1,-79,0,0,0,1,0,7,
+        0,0,0,6,0,1,0,0,
+        0,2,0,10,0,0,0,9,
+        2,0,11,0,0,0,12,0,
+        0,0,1,0,13,0,0,0,
+        2,0,14
+    };
+
+    private static final byte[] BadName2_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,91,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,13,66,97,100,78,
+        97,109,101,50,46,106,97,118,
+        97,12,0,4,0,5,1,0,
+        8,66,97,100,78,97,109,101,
+        50,1,0,16,106,97,118,97,
+        47,108,97,110,103,47,79,98,
+        106,101,99,116,0,33,0,2,
+        0,3,0,0,0,0,0,2,
+        0,1,0,4,0,5,0,1,
+        0,6,0,0,0,29,0,1,
+        0,1,0,0,0,5,42,-73,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,1,0,1,0,8,0,
+        9,0,2,0,6,0,0,0,
+        25,0,0,0,3,0,0,0,
+        1,-79,0,0,0,1,0,7,
+        0,0,0,6,0,1,0,0,
+        0,2,0,10,0,0,0,9,
+        2,0,11,0,0,0,12,0,
+        0,0,1,0,13,0,0,0,
+        2,0,14
+    };
+
+    private static final byte[] BadName3_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,59,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,13,66,97,100,78,
+        97,109,101,51,46,106,97,118,
+        97,12,0,4,0,5,1,0,
+        8,66,97,100,78,97,109,101,
+        51,1,0,16,106,97,118,97,
+        47,108,97,110,103,47,79,98,
+        106,101,99,116,0,33,0,2,
+        0,3,0,0,0,0,0,2,
+        0,1,0,4,0,5,0,1,
+        0,6,0,0,0,29,0,1,
+        0,1,0,0,0,5,42,-73,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,1,0,1,0,8,0,
+        9,0,2,0,6,0,0,0,
+        25,0,0,0,3,0,0,0,
+        1,-79,0,0,0,1,0,7,
+        0,0,0,6,0,1,0,0,
+        0,2,0,10,0,0,0,9,
+        2,0,11,0,0,0,12,0,
+        0,0,1,0,13,0,0,0,
+        2,0,14
+    };
+
+    private static final byte[] BadName4_bytes = {
+        -54,-2,-70,-66,0,0,0,52,
+        0,18,10,0,3,0,15,7,
+        0,16,7,0,17,1,0,6,
+        60,105,110,105,116,62,1,0,
+        3,40,41,86,1,0,4,67,
+        111,100,101,1,0,15,76,105,
+        110,101,78,117,109,98,101,114,
+        84,97,98,108,101,1,0,1,
+        109,1,0,5,40,73,73,41,
+        86,1,0,16,77,101,116,104,
+        111,100,80,97,114,97,109,101,
+        116,101,114,115,1,0,1,47,
+        1,0,1,98,1,0,10,83,
+        111,117,114,99,101,70,105,108,
+        101,1,0,13,66,97,100,78,
+        97,109,101,52,46,106,97,118,
+        97,12,0,4,0,5,1,0,
+        8,66,97,100,78,97,109,101,
+        52,1,0,16,106,97,118,97,
+        47,108,97,110,103,47,79,98,
+        106,101,99,116,0,33,0,2,
+        0,3,0,0,0,0,0,2,
+        0,1,0,4,0,5,0,1,
+        0,6,0,0,0,29,0,1,
+        0,1,0,0,0,5,42,-73,
+        0,1,-79,0,0,0,1,0,
+        7,0,0,0,6,0,1,0,
+        0,0,1,0,1,0,8,0,
+        9,0,2,0,6,0,0,0,
+        25,0,0,0,3,0,0,0,
+        1,-79,0,0,0,1,0,7,
+        0,0,0,6,0,1,0,0,
+        0,2,0,10,0,0,0,9,
+        2,0,11,0,0,0,12,0,
+        0,0,1,0,13,0,0,0,
+        2,0,14
+    };
+
+    private static class InMemoryClassLoader extends ClassLoader {
+        public Class<?> defineClass(String name, byte[] b) {
+            return defineClass(name, b, 0, b.length);
+        }
+    };
+
+    private static final InMemoryClassLoader loader = new InMemoryClassLoader();
+
+    private final Class<?>[] classes;
+
+    private BadClassFiles() throws ClassNotFoundException {
+        classes = new Class<?>[] {
+            loader.defineClass("EmptyName", EmptyName_bytes),
+            loader.defineClass("BadModifiers", BadModifiers_bytes),
+            loader.defineClass("BadNameIndex", BadNameIndex_bytes),
+            loader.defineClass("NameIndexOutOfBounds", NameIndexOutOfBounds_bytes),
+            loader.defineClass("ExtraParams", ExtraParams_bytes),
+            // Name with .
+            loader.defineClass("BadName1", BadName1_bytes),
+            // Name with [
+            loader.defineClass("BadName2", BadName2_bytes),
+            // Name with ;
+            loader.defineClass("BadName3", BadName3_bytes),
+            // Name with /
+            loader.defineClass("BadName4", BadName4_bytes)
+        };
+    }
+
+    public static void main(String... args)
+        throws NoSuchMethodException, IOException, ClassNotFoundException {
+        new BadClassFiles().run();
+    }
+
+    public void assertBadParameters(Class<?> cls) throws NoSuchMethodException {
+        try {
+            System.err.println("Trying " + cls);
+            final Method method = cls.getMethod("m", int.class, int.class);
+            final Parameter[] params = method.getParameters();
+            System.err.println("Name " + params[0].getName());
+            System.err.println("Did not see expected exception");
+            errors++;
+        } catch(MalformedParametersException e) {
+            System.err.println("Expected exception seen");
+        }
+    }
+
+    public void run() throws NoSuchMethodException {
+        for (Class<?> cls : classes)
+            assertBadParameters(cls);
+
+        if (errors != 0)
+            throw new RuntimeException(errors + " errors in test");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/reflect/Parameter/GetAnnotatedTypeTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * @compile -parameters GetAnnotatedTypeTest.java
+ * @run main GetAnnotatedTypeTest
+ * @summary javac should generate method parameters correctly.
+ */
+
+public class GetAnnotatedTypeTest {
+
+    public void meth(Object param) {}
+
+    public static void main(String[] args) throws NoSuchMethodException {
+        if (GetAnnotatedTypeTest.class.getMethod("meth", Object.class).getParameters()[0].getAnnotatedType().getType() != Object.class)
+            throw new RuntimeException("Parameter did not have the expected annotated type");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/PlainSocketImpl/CustomSocketImplFactory.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,107 @@
+/*
+ * 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 8024952
+ * @summary ClassCastException in PlainSocketImpl.accept() when using custom socketImpl
+ * @run main/othervm CustomSocketImplFactory
+ */
+
+import java.net.*;
+import java.io.*;
+
+public class CustomSocketImplFactory implements SocketImplFactory {
+
+    @Override
+    public SocketImpl createSocketImpl() {
+        try {
+            SocketImpl s = new CustomSocketImpl();
+            System.out.println("Created " + s);
+            return s;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        Socket.setSocketImplFactory(new CustomSocketImplFactory());
+        try (ServerSocket ss = new ServerSocket(0)) {
+            ss.setSoTimeout(1);
+            ss.accept();
+            System.out.println("PASS");
+        } catch (SocketTimeoutException | NullPointerException e) {
+            // Not a real socket impl
+        }
+    }
+
+    class CustomSocketImpl extends SocketImpl {
+
+        public void create(boolean stream) throws IOException {
+        }
+
+        public void connect(String host, int port) throws IOException {
+        }
+
+        public void connect(InetAddress addr, int port) throws IOException {
+        }
+
+        public void connect(SocketAddress addr, int timeout) throws IOException {
+        }
+
+        public void bind(InetAddress host, int port) throws IOException {
+        }
+
+        public void listen(int backlog) throws IOException {
+        }
+
+        public void accept(SocketImpl s) throws IOException {
+        }
+
+        public InputStream getInputStream() throws IOException {
+            return null;
+        }
+
+        public OutputStream getOutputStream() throws IOException {
+            return null;
+        }
+
+        public int available() throws IOException {
+            return 0;
+        }
+
+        public void close() throws IOException {
+        }
+
+        public void sendUrgentData(int data) throws IOException {
+        }
+
+        public Object getOption(int i) throws SocketException {
+            return null;
+        }
+
+        public void setOption(int i, Object o) throws SocketException {
+        }
+    }
+}
--- a/test/java/nio/file/Files/BytesAndLines.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/nio/file/Files/BytesAndLines.java	Tue Oct 08 14:57:32 2013 -0700
@@ -22,7 +22,9 @@
  */
 
 /* @test
- * @bug 7006126 8020669
+ * @bug 7006126 8020669 8024788
+ * @build BytesAndLines PassThroughFileSystem
+ * @run main BytesAndLines
  * @summary Unit test for methods for Files readAllBytes, readAllLines and
  *     and write methods.
  */
@@ -92,6 +94,16 @@
             byte[] data = Files.readAllBytes(pathStat);
             assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read");
         }
+
+        // test readAllBytes on custom file system
+        Path myfile = PassThroughFileSystem.create().getPath(file.toString());
+        for (int size=0; size<=1024; size+=512) {
+            byte[] b1 = new byte[size];
+            rand.nextBytes(b1);
+            Files.write(myfile, b1);
+            byte[] b2 = Files.readAllBytes(myfile);
+            assertTrue(Arrays.equals(b1, b2), "bytes not equal");
+        }
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/Provider/ProviderVersionCheck.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.security.Provider;
+import java.security.Security;
+import java.lang.Exception;
+
+/*
+ * @test
+ * @bug 7122707
+ * @run main/othervm ProviderVersionCheck
+ * @summary Verify all providers in the default Providers list have the proper
+ * version for the release
+ * @author Anthony Scarpino
+ */
+
+public class ProviderVersionCheck {
+
+    public static void main(String arg[]) throws Exception{
+
+        boolean failure = false;
+
+        for (Provider p: Security.getProviders()) {
+            System.out.print(p.getName() + " ");
+            if (p.getVersion() != 1.8d) {
+                System.out.println("failed. " + "Version received was " +
+                        p.getVersion());
+                failure = true;
+            } else {
+                System.out.println("passed.");
+            }
+        }
+
+        if (failure) {
+            throw new Exception("Provider(s) failed to have the expected " +
+                    "version value.");
+        }
+    }
+
+}
--- a/test/java/time/tck/java/time/AbstractTCKTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/AbstractTCKTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -68,6 +68,8 @@
 import java.io.ObjectStreamConstants;
 import java.io.Serializable;
 import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Formatter;
 
 /**
  * Base test class.
@@ -131,10 +133,10 @@
             assertEquals(dis.readByte(), ObjectStreamConstants.TC_NULL);  // no superclasses
             if (expectedBytes.length < 256) {
                 assertEquals(dis.readByte(), ObjectStreamConstants.TC_BLOCKDATA);
-                assertEquals(dis.readUnsignedByte(), expectedBytes.length);
+                assertEquals(dis.readUnsignedByte(), expectedBytes.length, "blockdata length incorrect");
             } else {
                 assertEquals(dis.readByte(), ObjectStreamConstants.TC_BLOCKDATALONG);
-                assertEquals(dis.readInt(), expectedBytes.length);
+                assertEquals(dis.readInt(), expectedBytes.length, "blockdatalong length incorrect");
             }
             byte[] input = new byte[expectedBytes.length];
             dis.readFully(input);
@@ -162,4 +164,33 @@
         }
     }
 
+
+    /**
+     * Utility method to dump a byte array in a java syntax.
+     * @param bytes and array of bytes
+     * @return a string containing the bytes formatted in java syntax
+     */
+    protected static String dumpSerialStream(byte[] bytes) {
+        StringBuilder sb = new StringBuilder(bytes.length * 5);
+        Formatter fmt = new Formatter(sb);
+        fmt.format("    byte[] bytes = {" );
+        final int linelen = 10;
+        for (int i = 0; i < bytes.length; i++) {
+            if (i % linelen == 0) {
+                fmt.format("%n        ");
+            }
+            fmt.format(" %3d,", bytes[i] & 0xff);
+            if ((i % linelen) == (linelen-1) || i == bytes.length - 1) {
+                fmt.format("  /*");
+                int s = i / linelen * linelen;
+                int k = i % linelen;
+                for (int j = 0; j <= k && s + j < bytes.length; j++) {
+                    fmt.format(" %c", bytes[s + j] & 0xff);
+                }
+                fmt.format(" */");
+            }
+        }
+        fmt.format("%n    };%n");
+        return sb.toString();
+    }
 }
--- a/test/java/time/tck/java/time/TCKClock_Fixed.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKClock_Fixed.java	Tue Oct 08 14:57:32 2013 -0700
@@ -80,12 +80,6 @@
     private static final ZoneId PARIS = ZoneId.of("Europe/Paris");
     private static final Instant INSTANT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2)).toInstant();
 
-    //-----------------------------------------------------------------------
-    public void test_isSerializable() throws IOException, ClassNotFoundException {
-        assertSerializable(Clock.fixed(INSTANT, ZoneOffset.UTC));
-        assertSerializable(Clock.fixed(INSTANT, PARIS));
-    }
-
     //-------------------------------------------------------------------------
     public void test_fixed_InstantZoneId() {
         Clock test = Clock.fixed(INSTANT, PARIS);
--- a/test/java/time/tck/java/time/TCKClock_Offset.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKClock_Offset.java	Tue Oct 08 14:57:32 2013 -0700
@@ -62,7 +62,6 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertSame;
 
-import java.io.IOException;
 import java.time.Clock;
 import java.time.Duration;
 import java.time.Instant;
@@ -84,11 +83,6 @@
     private static final Duration OFFSET = Duration.ofSeconds(2);
 
     //-----------------------------------------------------------------------
-    public void test_isSerializable() throws IOException, ClassNotFoundException {
-        assertSerializable(Clock.offset(Clock.system(PARIS), OFFSET));
-    }
-
-    //-----------------------------------------------------------------------
     public void test_offset_ClockDuration() {
         Clock test = Clock.offset(Clock.fixed(INSTANT, PARIS), OFFSET);
         //System.out.println(test.instant());
--- a/test/java/time/tck/java/time/TCKClock_System.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKClock_System.java	Tue Oct 08 14:57:32 2013 -0700
@@ -62,7 +62,6 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
 
-import java.io.IOException;
 import java.time.Clock;
 import java.time.Instant;
 import java.time.ZoneId;
@@ -80,13 +79,6 @@
     private static final ZoneId PARIS = ZoneId.of("Europe/Paris");
 
     //-----------------------------------------------------------------------
-    public void test_isSerializable() throws IOException, ClassNotFoundException {
-        assertSerializable(Clock.systemUTC());
-        assertSerializable(Clock.systemDefaultZone());
-        assertSerializable(Clock.system(PARIS));
-    }
-
-    //-----------------------------------------------------------------------
     public void test_instant() {
         Clock system = Clock.systemUTC();
         assertEquals(system.getZone(), ZoneOffset.UTC);
--- a/test/java/time/tck/java/time/TCKClock_Tick.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKClock_Tick.java	Tue Oct 08 14:57:32 2013 -0700
@@ -62,7 +62,6 @@
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertSame;
 
-import java.io.IOException;
 import java.time.Clock;
 import java.time.Duration;
 import java.time.Instant;
@@ -81,16 +80,7 @@
 
     private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow");
     private static final ZoneId PARIS = ZoneId.of("Europe/Paris");
-    private static final Duration AMOUNT = Duration.ofSeconds(2);
     private static final ZonedDateTime ZDT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2));
-    private static final Instant INSTANT = ZDT.toInstant();
-
-    //-----------------------------------------------------------------------
-    public void test_isSerializable() throws IOException, ClassNotFoundException {
-        assertSerializable(Clock.tickSeconds(PARIS));
-        assertSerializable(Clock.tickMinutes(MOSCOW));
-        assertSerializable(Clock.tick(Clock.fixed(INSTANT, PARIS), AMOUNT));
-    }
 
     //-----------------------------------------------------------------------
     public void test_tick_ClockDuration_250millis() {
--- a/test/java/time/tck/java/time/TCKDuration.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKDuration.java	Tue Oct 08 14:57:32 2013 -0700
@@ -77,6 +77,7 @@
 import java.time.DateTimeException;
 import java.time.Duration;
 import java.time.Instant;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Period;
@@ -104,26 +105,6 @@
     private static final long CYCLE_SECS = 146097L * 86400L;
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(Duration.ofHours(5));
-        assertSerializable(Duration.ofHours(0));
-        assertSerializable(Duration.ofHours(-5));
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(1);
-            dos.writeLong(654321);
-            dos.writeInt(123456789);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     // constants
     //-----------------------------------------------------------------------
     @Test
@@ -863,10 +844,17 @@
         assertEquals(Duration.between(end, start), Duration.between(start, end).negated());
     }
 
-    @Test(expectedExceptions=DateTimeException.class)
+    @Test
     public void factory_between_TemporalTemporal_mixedTypes() {
         Instant start = Instant.ofEpochSecond(1);
         ZonedDateTime end = Instant.ofEpochSecond(4).atZone(ZoneOffset.UTC);
+        assertEquals(Duration.between(start, end), Duration.ofSeconds(3));
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void factory_between_TemporalTemporal_invalidMixedTypes() {
+        Instant start = Instant.ofEpochSecond(1);
+        LocalDate end = LocalDate.of(2010, 6, 20);
         Duration.between(start, end);
     }
 
--- a/test/java/time/tck/java/time/TCKInstant.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKInstant.java	Tue Oct 08 14:57:32 2013 -0700
@@ -84,6 +84,7 @@
 import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.OffsetDateTime;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
@@ -155,24 +156,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(Instant.ofEpochMilli(134l));
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(2);
-            dos.writeLong(654321);
-            dos.writeInt(123456789);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(Instant.ofEpochSecond(654321, 123456789), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     private void check(Instant instant, long epochSecs, int nos) {
         assertEquals(instant.getEpochSecond(), epochSecs);
         assertEquals(instant.getNano(), nos);
@@ -1818,7 +1801,7 @@
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) {
         Instant i1 = Instant.ofEpochSecond(seconds1, nanos1);
         Instant i2 = Instant.ofEpochSecond(seconds2, nanos2);
         long amount = i1.until(i2, unit);
@@ -1826,25 +1809,46 @@
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit_negated(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) {
         Instant i1 = Instant.ofEpochSecond(seconds1, nanos1);
         Instant i2 = Instant.ofEpochSecond(seconds2, nanos2);
         long amount = i2.until(i1, unit);
         assertEquals(amount, -expected);
     }
 
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(long seconds1, int nanos1, long seconds2, long nanos2, TemporalUnit unit, long expected) {
+        Instant i1 = Instant.ofEpochSecond(seconds1, nanos1);
+        Instant i2 = Instant.ofEpochSecond(seconds2, nanos2);
+        long amount = unit.between(i1, i2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        Instant start = Instant.ofEpochSecond(12, 3000);
+        OffsetDateTime end = start.plusSeconds(2).atOffset(ZoneOffset.ofHours(2));
+        assertEquals(start.until(end, SECONDS), 2);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidType() {
+        Instant start = Instant.ofEpochSecond(12, 3000);
+        start.until(LocalTime.of(11, 30), SECONDS);
+    }
+
     @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
-    public void test_periodUntil_TemporalUnit_unsupportedUnit() {
+    public void test_until_TemporalUnit_unsupportedUnit() {
         TEST_12345_123456789.until(TEST_12345_123456789, MONTHS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullEnd() {
+    public void test_until_TemporalUnit_nullEnd() {
         TEST_12345_123456789.until(null, HOURS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullUnit() {
+    public void test_until_TemporalUnit_nullUnit() {
         TEST_12345_123456789.until(TEST_12345_123456789, null);
     }
 
--- a/test/java/time/tck/java/time/TCKLocalDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKLocalDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -196,28 +196,6 @@
         return list;
     }
 
-
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(TEST_2007_07_15);
-        assertSerializable(LocalDate.MIN);
-        assertSerializable(LocalDate.MAX);
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(3);
-            dos.writeInt(2012);
-            dos.writeByte(9);
-            dos.writeByte(16);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes);
-    }
-
     //-----------------------------------------------------------------------
     private void check(LocalDate test, int y, int m, int d) {
         assertEquals(test.getYear(), y);
@@ -1745,29 +1723,48 @@
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
         long amount = date1.until(date2, unit);
         assertEquals(amount, expected);
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
         long amount = date2.until(date1, unit);
         assertEquals(amount, -expected);
     }
 
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
+        long amount = unit.between(date1, date2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        LocalDate start = LocalDate.of(2010, 6, 30);
+        OffsetDateTime end = start.plusDays(2).atStartOfDay().atOffset(OFFSET_PONE);
+        assertEquals(start.until(end, DAYS), 2);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidType() {
+        LocalDate start = LocalDate.of(2010, 6, 30);
+        start.until(LocalTime.of(11, 30), DAYS);
+    }
+
     @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
-    public void test_periodUntil_TemporalUnit_unsupportedUnit() {
+    public void test_until_TemporalUnit_unsupportedUnit() {
         TEST_2007_07_15.until(TEST_2007_07_15, HOURS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullEnd() {
+    public void test_until_TemporalUnit_nullEnd() {
         TEST_2007_07_15.until(null, DAYS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullUnit() {
+    public void test_until_TemporalUnit_nullUnit() {
         TEST_2007_07_15.until(TEST_2007_07_15, null);
     }
 
--- a/test/java/time/tck/java/time/TCKLocalDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKLocalDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -242,31 +242,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(TEST_2007_07_15_12_30_40_987654321);
-        assertSerializable(LocalDateTime.MIN);
-        assertSerializable(LocalDateTime.MAX);
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(5);
-            dos.writeInt(2012);
-            dos.writeByte(9);
-            dos.writeByte(16);
-            dos.writeByte(22);
-            dos.writeByte(17);
-            dos.writeByte(59);
-            dos.writeInt(459_000_000);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     // constants
     //-----------------------------------------------------------------------
     @Test
@@ -2920,24 +2895,43 @@
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
         long amount = dt1.until(dt2, unit);
         assertEquals(amount, expected);
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
         long amount = dt2.until(dt1, unit);
         assertEquals(amount, -expected);
     }
 
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
+        long amount = unit.between(dt1, dt2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30);
+        OffsetDateTime end = start.plusDays(2).atOffset(OFFSET_PONE);
+        assertEquals(start.until(end, DAYS), 2);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidType() {
+        LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30);
+        start.until(LocalTime.of(11, 30), DAYS);
+    }
+
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullEnd() {
+    public void test_until_TemporalUnit_nullEnd() {
         TEST_2007_07_15_12_30_40_987654321.until(null, HOURS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullUnit() {
+    public void test_until_TemporalUnit_nullUnit() {
         TEST_2007_07_15_12_30_40_987654321.until(TEST_2007_07_15_12_30_40_987654321, null);
     }
 
--- a/test/java/time/tck/java/time/TCKLocalTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKLocalTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -191,64 +191,7 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(TEST_12_30_40_987654321);
-        assertSerializable(LocalTime.MIN);
-        assertSerializable(LocalTime.MAX);
-    }
 
-    @Test
-    public void test_serialization_format_h() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(4);
-            dos.writeByte(-1 - 22);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(LocalTime.of(22, 0), bytes);
-    }
-
-    @Test
-    public void test_serialization_format_hm() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(4);
-            dos.writeByte(22);
-            dos.writeByte(-1 - 17);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(LocalTime.of(22, 17), bytes);
-    }
-
-    @Test
-    public void test_serialization_format_hms() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(4);
-            dos.writeByte(22);
-            dos.writeByte(17);
-            dos.writeByte(-1 - 59);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(LocalTime.of(22, 17, 59), bytes);
-    }
-
-    @Test
-    public void test_serialization_format_hmsn() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(4);
-            dos.writeByte(22);
-            dos.writeByte(17);
-            dos.writeByte(59);
-            dos.writeInt(459_000_000);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(LocalTime.of(22, 17, 59, 459_000_000), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     private void check(LocalTime test, int h, int m, int s, int n) {
         assertEquals(test.getHour(), h);
         assertEquals(test.getMinute(), m);
@@ -2028,29 +1971,48 @@
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
         long amount = time1.until(time2, unit);
         assertEquals(amount, expected);
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
         long amount = time2.until(time1, unit);
         assertEquals(amount, -expected);
     }
 
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
+        long amount = unit.between(time1, time2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        LocalTime start = LocalTime.of(11, 30);
+        LocalDateTime end = start.plusSeconds(2).atDate(LocalDate.of(2010, 6, 30));
+        assertEquals(start.until(end, SECONDS), 2);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidType() {
+        LocalTime start = LocalTime.of(11, 30);
+        start.until(LocalDate.of(2010, 6, 30), SECONDS);
+    }
+
     @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
-    public void test_periodUntil_TemporalUnit_unsupportedUnit() {
+    public void test_until_TemporalUnit_unsupportedUnit() {
         TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, DAYS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullEnd() {
+    public void test_until_TemporalUnit_nullEnd() {
         TEST_12_30_40_987654321.until(null, HOURS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullUnit() {
+    public void test_until_TemporalUnit_nullUnit() {
         TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, null);
     }
 
--- a/test/java/time/tck/java/time/TCKMonthDay.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKMonthDay.java	Tue Oct 08 14:57:32 2013 -0700
@@ -137,24 +137,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws ClassNotFoundException, IOException {
-        assertSerializable(TEST_07_15);
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(13);       // java.time.temporal.Ser.MONTH_DAY_TYPE
-            dos.writeByte(9);
-            dos.writeByte(16);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(MonthDay.of(9, 16), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     void check(MonthDay test, int m, int d) {
         assertEquals(test.getMonth().getValue(), m);
         assertEquals(test.getDayOfMonth(), d);
--- a/test/java/time/tck/java/time/TCKOffsetDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKOffsetDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -91,6 +91,13 @@
 import static java.time.temporal.ChronoField.YEAR;
 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
 import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.FOREVER;
+import static java.time.temporal.ChronoUnit.HALF_DAYS;
+import static java.time.temporal.ChronoUnit.HOURS;
+import static java.time.temporal.ChronoUnit.MICROS;
+import static java.time.temporal.ChronoUnit.MILLIS;
+import static java.time.temporal.ChronoUnit.MINUTES;
+import static java.time.temporal.ChronoUnit.MONTHS;
 import static java.time.temporal.ChronoUnit.NANOS;
 import static java.time.temporal.ChronoUnit.SECONDS;
 import static org.testng.Assert.assertEquals;
@@ -210,43 +217,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(TEST_2008_6_30_11_30_59_000000500);
-        assertSerializable(OffsetDateTime.MIN);
-        assertSerializable(OffsetDateTime.MAX);
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(10);       // java.time.Ser.OFFSET_DATE_TIME_TYPE
-        }
-        byte[] bytes = baos.toByteArray();
-        ByteArrayOutputStream baosDateTime = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baosDateTime) ) {
-            dos.writeByte(5);
-            dos.writeInt(2012);
-            dos.writeByte(9);
-            dos.writeByte(16);
-            dos.writeByte(22);
-            dos.writeByte(17);
-            dos.writeByte(59);
-            dos.writeInt(464_000_000);
-        }
-        byte[] bytesDateTime = baosDateTime.toByteArray();
-        ByteArrayOutputStream baosOffset = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baosOffset) ) {
-            dos.writeByte(8);
-            dos.writeByte(4);  // quarter hours stored: 3600 / 900
-        }
-        byte[] bytesOffset = baosOffset.toByteArray();
-        LocalDateTime ldt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 464_000_000);
-        assertSerializedBySer(OffsetDateTime.of(ldt, ZoneOffset.ofHours(1)), bytes, bytesDateTime, bytesOffset);
-    }
-
-    //-----------------------------------------------------------------------
     // constants
     //-----------------------------------------------------------------------
     @Test
@@ -1166,6 +1136,74 @@
     }
 
     //-----------------------------------------------------------------------
+    // until(Temporal, TemporalUnit)
+    //-----------------------------------------------------------------------
+    @DataProvider(name="periodUntilUnit")
+    Object[][] data_untilUnit() {
+        return new Object[][] {
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 13, 1, 1, 0, OFFSET_PONE), HALF_DAYS, 1},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), HOURS, 1},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MINUTES, 60},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), SECONDS, 3600},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MILLIS, 3600*1000},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), MICROS, 3600*1000*1000L},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE), NANOS, 3600*1000*1000L*1000},
+
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 14, 1, 1, 0, OFFSET_PTWO), HALF_DAYS, 1},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), HOURS, 1},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MINUTES, 60},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), SECONDS, 3600},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MILLIS, 3600*1000},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), MICROS, 3600*1000*1000L},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 6, 30, 3, 1, 1, 0, OFFSET_PTWO), NANOS, 3600*1000*1000L*1000},
+
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 7, 1, 1, 1, 0, 999999999, OFFSET_PONE), DAYS, 0},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 7, 1, 1, 1, 1, 0, OFFSET_PONE), DAYS, 1},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 29, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 1},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 30, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 2},
+                {OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE), OffsetDateTime.of(2010, 8, 31, 1, 1, 1, 0, OFFSET_PONE), MONTHS, 2},
+        };
+    }
+
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) {
+        long amount = odt1.until(odt2, unit);
+        assertEquals(amount, expected);
+    }
+
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_negated(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) {
+        long amount = odt2.until(odt1, unit);
+        assertEquals(amount, -expected);
+    }
+
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(OffsetDateTime odt1, OffsetDateTime odt2, TemporalUnit unit, long expected) {
+        long amount = unit.between(odt1, odt2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        OffsetDateTime odt = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE);
+        ZonedDateTime zdt = odt.plusSeconds(3).toZonedDateTime();
+        assertEquals(odt.until(zdt, SECONDS), 3);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidType() {
+        OffsetDateTime odt = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE);
+        odt.until(Instant.ofEpochSecond(12), SECONDS);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidTemporalUnit() {
+        OffsetDateTime odt1 = OffsetDateTime.of(2010, 6, 30, 1, 1, 1, 0, OFFSET_PONE);
+        OffsetDateTime odt2 = OffsetDateTime.of(2010, 6, 30, 2, 1, 1, 0, OFFSET_PONE);
+        odt1.until(odt2, FOREVER);
+    }
+
+    //-----------------------------------------------------------------------
     // format(DateTimeFormatter)
     //-----------------------------------------------------------------------
     @Test
--- a/test/java/time/tck/java/time/TCKOffsetTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKOffsetTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -184,40 +184,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(TEST_11_30_59_500_PONE);
-        assertSerializable(OffsetTime.MIN);
-        assertSerializable(OffsetTime.MAX);
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(9);       // java.time.Ser.OFFSET_TIME_TYPE
-        }
-        byte[] bytes = baos.toByteArray();
-        ByteArrayOutputStream baosTime = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baosTime) ) {
-            dos.writeByte(4);
-            dos.writeByte(22);
-            dos.writeByte(17);
-            dos.writeByte(59);
-            dos.writeInt(464_000_000);
-        }
-        byte[] bytesTime = baosTime.toByteArray();
-        ByteArrayOutputStream baosOffset = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baosOffset) ) {
-            dos.writeByte(8);
-            dos.writeByte(4);  // quarter hours stored: 3600 / 900
-        }
-        byte[] bytesOffset = baosOffset.toByteArray();
-        assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes,
-                bytesTime, bytesOffset);
-    }
-
-    //-----------------------------------------------------------------------
     // constants
     //-----------------------------------------------------------------------
     @Test
@@ -1103,49 +1069,61 @@
     // until(Temporal, TemporalUnit)
     //-----------------------------------------------------------------------
     @DataProvider(name="periodUntilUnit")
-    Object[][] data_periodUntilUnit() {
+    Object[][] data_untilUnit() {
         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(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(13, 1, 1, 0, OFFSET_PONE), HALF_DAYS, 1},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), HOURS, 1},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MINUTES, 60},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), SECONDS, 3600},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MILLIS, 3600*1000},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), MICROS, 3600*1000*1000L},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(2, 1, 1, 0, OFFSET_PONE), 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},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(14, 1, 1, 0, OFFSET_PTWO), HALF_DAYS, 1},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), HOURS, 1},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MINUTES, 60},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), SECONDS, 3600},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MILLIS, 3600*1000},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), MICROS, 3600*1000*1000L},
+                {OffsetTime.of(1, 1, 1, 0, OFFSET_PONE), OffsetTime.of(3, 1, 1, 0, OFFSET_PTWO), NANOS, 3600*1000*1000L*1000},
         };
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
         long amount = offsetTime1.until(offsetTime2, unit);
         assertEquals(amount, expected);
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
         long amount = offsetTime2.until(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.until(offsetDateTime, SECONDS);
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
+        long amount = unit.between(offsetTime1, offsetTime2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        OffsetTime offsetTime = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE);
+        OffsetDateTime offsetDateTime = offsetTime.plusSeconds(3).atDate(LocalDate.of(1980, 2, 10));
+        assertEquals(offsetTime.until(offsetDateTime, SECONDS), 3);
     }
 
     @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));
+    public void test_until_invalidType() {
+        OffsetTime offsetTime = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE);
+        offsetTime.until(LocalDate.of(1980, 2, 10), SECONDS);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidTemporalUnit() {
+        OffsetTime offsetTime1 = OffsetTime.of(1, 1, 1, 0, OFFSET_PONE);
+        OffsetTime offsetTime2 = OffsetTime.of(2, 1, 1, 0, OFFSET_PONE);
         offsetTime1.until(offsetTime2, MONTHS);
     }
 
--- a/test/java/time/tck/java/time/TCKPeriod.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKPeriod.java	Tue Oct 08 14:57:32 2013 -0700
@@ -60,6 +60,7 @@
 package tck.java.time;
 
 import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.HOURS;
 import static java.time.temporal.ChronoUnit.YEARS;
 import static org.testng.Assert.assertEquals;
 
@@ -67,6 +68,7 @@
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.Period;
+import java.time.chrono.ThaiBuddhistChronology;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.Temporal;
@@ -87,14 +89,6 @@
 public class TCKPeriod extends AbstractTCKTest {
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(Period.ZERO);
-        assertSerializable(Period.ofDays(1));
-        assertSerializable(Period.of(1, 2, 3));
-    }
-
-    //-----------------------------------------------------------------------
     // ofYears(int)
     //-----------------------------------------------------------------------
     @Test
@@ -221,6 +215,41 @@
     }
 
     @Test(expectedExceptions = DateTimeException.class)
+    public void factory_from_TemporalAmount_DaysHours() {
+        TemporalAmount amount = new TemporalAmount() {
+            @Override
+            public long get(TemporalUnit unit) {
+                if (unit == DAYS) {
+                    return 1;
+                } else {
+                    return 2;
+                }
+            }
+            @Override
+            public List<TemporalUnit> getUnits() {
+                List<TemporalUnit> list = new ArrayList<>();
+                list.add(DAYS);
+                list.add(HOURS);
+                return list;
+            }
+            @Override
+            public Temporal addTo(Temporal temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public Temporal subtractFrom(Temporal temporal) {
+                throw new UnsupportedOperationException();
+            }
+        };
+        Period.from(amount);
+    }
+
+    @Test(expectedExceptions = DateTimeException.class)
+    public void factory_from_TemporalAmount_NonISO() {
+        Period.from(ThaiBuddhistChronology.INSTANCE.period(1, 1, 1));
+    }
+
+    @Test(expectedExceptions = DateTimeException.class)
     public void factory_from_TemporalAmount_Duration() {
         Period.from(Duration.ZERO);
     }
@@ -602,10 +631,45 @@
     }
 
     @Test(dataProvider="plus")
-    public void test_plus(Period base, Period add, Period expected) {
+    public void test_plus_TemporalAmount(Period base, Period add, Period expected) {
         assertEquals(base.plus(add), expected);
     }
 
+    @Test(expectedExceptions = DateTimeException.class)
+    public void test_plus_TemporalAmount_nonISO() {
+        pymd(4, 5, 6).plus(ThaiBuddhistChronology.INSTANCE.period(1, 0, 0));
+    }
+
+    @Test(expectedExceptions = DateTimeException.class)
+    public void test_plus_TemporalAmount_DaysHours() {
+        TemporalAmount amount = new TemporalAmount() {
+            @Override
+            public long get(TemporalUnit unit) {
+                if (unit == DAYS) {
+                    return 1;
+                } else {
+                    return 2;
+                }
+            }
+            @Override
+            public List<TemporalUnit> getUnits() {
+                List<TemporalUnit> list = new ArrayList<>();
+                list.add(DAYS);
+                list.add(HOURS);
+                return list;
+            }
+            @Override
+            public Temporal addTo(Temporal temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public Temporal subtractFrom(Temporal temporal) {
+                throw new UnsupportedOperationException();
+            }
+        };
+        pymd(4, 5, 6).plus(amount);
+    }
+
     //-----------------------------------------------------------------------
     // plusYears()
     //-----------------------------------------------------------------------
@@ -712,10 +776,45 @@
     }
 
     @Test(dataProvider="minus")
-    public void test_minus(Period base, Period subtract, Period expected) {
+    public void test_minus_TemporalAmount(Period base, Period subtract, Period expected) {
         assertEquals(base.minus(subtract), expected);
     }
 
+    @Test(expectedExceptions = DateTimeException.class)
+    public void test_minus_TemporalAmount_nonISO() {
+        pymd(4, 5, 6).minus(ThaiBuddhistChronology.INSTANCE.period(1, 0, 0));
+    }
+
+    @Test(expectedExceptions = DateTimeException.class)
+    public void test_minus_TemporalAmount_DaysHours() {
+        TemporalAmount amount = new TemporalAmount() {
+            @Override
+            public long get(TemporalUnit unit) {
+                if (unit == DAYS) {
+                    return 1;
+                } else {
+                    return 2;
+                }
+            }
+            @Override
+            public List<TemporalUnit> getUnits() {
+                List<TemporalUnit> list = new ArrayList<>();
+                list.add(DAYS);
+                list.add(HOURS);
+                return list;
+            }
+            @Override
+            public Temporal addTo(Temporal temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public Temporal subtractFrom(Temporal temporal) {
+                throw new UnsupportedOperationException();
+            }
+        };
+        pymd(4, 5, 6).minus(amount);
+    }
+
     //-----------------------------------------------------------------------
     // minusYears()
     //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/TCKYear.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKYear.java	Tue Oct 08 14:57:32 2013 -0700
@@ -65,10 +65,8 @@
 import static java.time.temporal.ChronoUnit.CENTURIES;
 import static java.time.temporal.ChronoUnit.DAYS;
 import static java.time.temporal.ChronoUnit.DECADES;
-import static java.time.temporal.ChronoUnit.HOURS;
 import static java.time.temporal.ChronoUnit.MILLENNIA;
 import static java.time.temporal.ChronoUnit.MONTHS;
-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;
@@ -90,8 +88,8 @@
 import java.time.YearMonth;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
+import java.time.chrono.IsoChronology;
 import java.time.chrono.IsoEra;
-import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
 import java.time.temporal.ChronoField;
@@ -152,25 +150,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(Year.of(2));
-        assertSerializable(Year.of(0));
-        assertSerializable(Year.of(-2));
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(11);       // java.time.temporal.Ser.YEAR_TYPE
-            dos.writeInt(2012);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(Year.of(2012), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     // now()
     //-----------------------------------------------------------------------
     @Test
@@ -248,17 +227,17 @@
 
     //-----------------------------------------------------------------------
     @Test
-    public void test_factory_CalendricalObject() {
+    public void test_from_TemporalAccessor() {
         assertEquals(Year.from(LocalDate.of(2007, 7, 15)), Year.of(2007));
     }
 
     @Test(expectedExceptions=DateTimeException.class)
-    public void test_factory_CalendricalObject_invalid_noDerive() {
+    public void test_from_TemporalAccessor_invalid_noDerive() {
         Year.from(LocalTime.of(12, 30));
     }
 
     @Test(expectedExceptions=NullPointerException.class)
-    public void test_factory_CalendricalObject_null() {
+    public void test_from_TemporalAccessor_null() {
         Year.from((TemporalAccessor) null);
     }
 
@@ -616,13 +595,13 @@
         };
     }
 
-    @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit")
+    @Test(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);
+                base.plus(amount, unit);
                 fail();
             } catch (Exception ex) {
                 assertTrue(expectedEx.isInstance(ex));
@@ -748,7 +727,7 @@
         };
     }
 
-    @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit")
+    @Test(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);
@@ -807,7 +786,7 @@
     //-----------------------------------------------------------------------
     // with(TemporalField, long)
     //-----------------------------------------------------------------------
-    @Test(groups={"tck"})
+    @Test
     public void test_with() {
         Year base = Year.of(5);
         Year result = base.with(ChronoField.ERA, 0);
@@ -942,29 +921,48 @@
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit(Year year1, Year year2, TemporalUnit unit, long expected) {
         long amount = year1.until(year2, unit);
         assertEquals(amount, expected);
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit_negated(Year year1, Year year2, TemporalUnit unit, long expected) {
         long amount = year2.until(year1, unit);
         assertEquals(amount, -expected);
     }
 
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(Year year1, Year year2, TemporalUnit unit, long expected) {
+        long amount = unit.between(year1, year2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        Year start = Year.of(2010);
+        YearMonth end = start.plusYears(2).atMonth(Month.APRIL);
+        assertEquals(start.until(end, YEARS), 2);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidType() {
+        Year start = Year.of(2010);
+        start.until(LocalTime.of(11, 30), YEARS);
+    }
+
     @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
-    public void test_periodUntil_TemporalUnit_unsupportedUnit() {
+    public void test_until_TemporalUnit_unsupportedUnit() {
         TEST_2008.until(TEST_2008, MONTHS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullEnd() {
+    public void test_until_TemporalUnit_nullEnd() {
         TEST_2008.until(null, DAYS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullUnit() {
+    public void test_until_TemporalUnit_nullUnit() {
         TEST_2008.until(TEST_2008, null);
     }
 
--- a/test/java/time/tck/java/time/TCKYearMonth.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKYearMonth.java	Tue Oct 08 14:57:32 2013 -0700
@@ -70,7 +70,6 @@
 import static java.time.temporal.ChronoUnit.HOURS;
 import static java.time.temporal.ChronoUnit.MILLENNIA;
 import static java.time.temporal.ChronoUnit.MONTHS;
-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;
@@ -157,24 +156,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws IOException, ClassNotFoundException {
-        assertSerializable(TEST_2008_06);
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(12);       // java.time.temporal.Ser.YEAR_MONTH_TYPE
-            dos.writeInt(2012);
-            dos.writeByte(9);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(YearMonth.of(2012, 9), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     void check(YearMonth test, int y, int m) {
         assertEquals(test.getYear(), y);
         assertEquals(test.getMonth().getValue(), m);
@@ -288,17 +269,17 @@
 
     //-----------------------------------------------------------------------
     @Test
-    public void test_factory_CalendricalObject() {
+    public void test_from_TemporalAccessor() {
         assertEquals(YearMonth.from(LocalDate.of(2007, 7, 15)), YearMonth.of(2007, 7));
     }
 
     @Test(expectedExceptions=DateTimeException.class)
-    public void test_factory_CalendricalObject_invalid_noDerive() {
+    public void test_from_TemporalAccessor_invalid_noDerive() {
         YearMonth.from(LocalTime.of(12, 30));
     }
 
     @Test(expectedExceptions=NullPointerException.class)
-    public void test_factory_CalendricalObject_null() {
+    public void test_from_TemporalAccessor_null() {
         YearMonth.from((TemporalAccessor) null);
     }
 
@@ -786,7 +767,7 @@
         };
     }
 
-    @Test(groups={"tck"}, dataProvider="plus_long_TemporalUnit")
+    @Test(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);
@@ -838,7 +819,7 @@
         };
     }
 
-    @Test(groups={"tck"}, dataProvider="plus_TemporalAmount")
+    @Test(dataProvider="plus_TemporalAmount")
     public void test_plus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) {
         if (expectedEx == null) {
             assertEquals(base.plus(temporalAmount), expectedYearMonth);
@@ -1001,7 +982,7 @@
         };
     }
 
-    @Test(groups={"tck"}, dataProvider="minus_long_TemporalUnit")
+    @Test(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);
@@ -1053,7 +1034,7 @@
         };
     }
 
-    @Test(groups={"tck"}, dataProvider="minus_TemporalAmount")
+    @Test(dataProvider="minus_TemporalAmount")
     public void test_minus_TemporalAmount(YearMonth base, TemporalAmount temporalAmount, YearMonth expectedYearMonth, Class expectedEx) {
         if (expectedEx == null) {
             assertEquals(base.minus(temporalAmount), expectedYearMonth);
@@ -1261,29 +1242,48 @@
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
         long amount = ym1.until(ym2, unit);
         assertEquals(amount, expected);
     }
 
     @Test(dataProvider="periodUntilUnit")
-    public void test_periodUntil_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
+    public void test_until_TemporalUnit_negated(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
         long amount = ym2.until(ym1, unit);
         assertEquals(amount, -expected);
     }
 
+    @Test(dataProvider="periodUntilUnit")
+    public void test_until_TemporalUnit_between(YearMonth ym1, YearMonth ym2, TemporalUnit unit, long expected) {
+        long amount = unit.between(ym1, ym2);
+        assertEquals(amount, expected);
+    }
+
+    @Test
+    public void test_until_convertedType() {
+        YearMonth start = YearMonth.of(2010, 6);
+        LocalDate end = start.plusMonths(2).atDay(12);
+        assertEquals(start.until(end, MONTHS), 2);
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_until_invalidType() {
+        YearMonth start = YearMonth.of(2010, 6);
+        start.until(LocalTime.of(11, 30), MONTHS);
+    }
+
     @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
-    public void test_periodUntil_TemporalUnit_unsupportedUnit() {
+    public void test_until_TemporalUnit_unsupportedUnit() {
         TEST_2008_06.until(TEST_2008_06, HOURS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullEnd() {
+    public void test_until_TemporalUnit_nullEnd() {
         TEST_2008_06.until(null, DAYS);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
-    public void test_periodUntil_TemporalUnit_nullUnit() {
+    public void test_until_TemporalUnit_nullUnit() {
         TEST_2008_06.until(TEST_2008_06, null);
     }
 
--- a/test/java/time/tck/java/time/TCKZoneId.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKZoneId.java	Tue Oct 08 14:57:32 2013 -0700
@@ -93,110 +93,6 @@
 public class TCKZoneId extends AbstractTCKTest {
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(ZoneId.of("Europe/London"));
-        assertSerializable(ZoneId.of("America/Chicago"));
-    }
-
-    @Test
-    public void test_serialization_format() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(7);
-            dos.writeUTF("Europe/London");
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(ZoneId.of("Europe/London"), bytes);
-    }
-
-    @Test
-    public void test_deserialization_lenient_characters() throws Exception {
-        // an ID can be loaded without validation during deserialization
-        String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-";
-        ZoneId deser = deserialize(id);
-        // getId, equals, hashCode, toString and normalized are OK
-        assertEquals(deser.getId(), id);
-        assertEquals(deser.toString(), id);
-        assertEquals(deser, deser);
-        assertEquals(deser.hashCode(), deser.hashCode());
-        assertEquals(deser.normalized(), deser);
-        // getting the rules is not
-        try {
-            deser.getRules();
-            fail();
-        } catch (ZoneRulesException ex) {
-            // expected
-        }
-    }
-
-    @Test(expectedExceptions=DateTimeException.class)
-    public void test_deserialization_lenient_badCharacters() throws Exception {
-        // an ID can be loaded without validation during deserialization
-        // but there is a check to ensure the ID format is valid
-        deserialize("|!?");
-    }
-
-    @Test(dataProvider="offsetBasedValid")
-    public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception {
-        ZoneId deserialized = deserialize(input);
-        assertEquals(deserialized, ZoneId.of(input));
-        assertEquals(deserialized, ZoneId.of(resolvedId));
-    }
-
-    @Test(dataProvider="offsetBasedValidPrefix")
-    public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId, String offsetId) throws Exception {
-        ZoneId deserialized = deserialize("UTC" + input);
-        assertEquals(deserialized, ZoneId.of("UTC" + input));
-        assertEquals(deserialized, ZoneId.of("UTC" + resolvedId));
-    }
-
-    @Test(dataProvider="offsetBasedValidPrefix")
-    public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId, String offsetId) throws Exception {
-        ZoneId deserialized = deserialize("GMT" + input);
-        assertEquals(deserialized, ZoneId.of("GMT" + input));
-        assertEquals(deserialized, ZoneId.of("GMT" + resolvedId));
-    }
-
-    @Test(dataProvider="offsetBasedValidPrefix")
-    public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId, String offsetId) throws Exception {
-        ZoneId deserialized = deserialize("UT" + input);
-        assertEquals(deserialized, ZoneId.of("UT" + input));
-        assertEquals(deserialized, ZoneId.of("UT" + resolvedId));
-    }
-
-    private ZoneId deserialize(String id) throws Exception {
-        String serClass = ZoneId.class.getPackage().getName() + ".Ser";
-        Class<?> serCls = Class.forName(serClass);
-        Field field = serCls.getDeclaredField("serialVersionUID");
-        field.setAccessible(true);
-        long serVer = (Long) field.get(null);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos)) {
-            dos.writeShort(ObjectStreamConstants.STREAM_MAGIC);
-            dos.writeShort(ObjectStreamConstants.STREAM_VERSION);
-            dos.writeByte(ObjectStreamConstants.TC_OBJECT);
-            dos.writeByte(ObjectStreamConstants.TC_CLASSDESC);
-            dos.writeUTF(serClass);
-            dos.writeLong(serVer);
-            dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA);
-            dos.writeShort(0);  // number of fields
-            dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);  // end of classdesc
-            dos.writeByte(ObjectStreamConstants.TC_NULL);  // no superclasses
-            dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA);
-            dos.writeByte(1 + 2 + id.length());  // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF)
-            dos.writeByte(7);  // ZoneId
-            dos.writeUTF(id);
-            dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);  // end of blockdata
-        }
-        ZoneId deser = null;
-        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
-            deser = (ZoneId) ois.readObject();
-        }
-        return deser;
-    }
-
-    //-----------------------------------------------------------------------
     // OLD_SHORT_IDS
     //-----------------------------------------------------------------------
     public void test_constant_OLD_IDS_PRE_2005() {
--- a/test/java/time/tck/java/time/TCKZoneOffset.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKZoneOffset.java	Tue Oct 08 14:57:32 2013 -0700
@@ -121,46 +121,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws Exception {
-        assertSerializable(ZoneOffset.of("+01:30"));
-    }
-
-    @Test
-    public void test_serialization_format_quarterPositive() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(8);
-            dos.writeByte(6);  // stored as quarter hours
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(ZoneOffset.ofHoursMinutes(1, 30), bytes);
-    }
-
-    @Test
-    public void test_serialization_format_quarterNegative() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(8);
-            dos.writeByte(-10);  // stored as quarter hours
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(ZoneOffset.ofHoursMinutes(-2, -30), bytes);
-    }
-
-    @Test
-    public void test_serialization_format_full() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(8);
-            dos.writeByte(127);
-            dos.writeInt(53265);
-        }
-        byte[] bytes = baos.toByteArray();
-        assertSerializedBySer(ZoneOffset.ofTotalSeconds(53265), bytes);
-    }
-
-    //-----------------------------------------------------------------------
     // constants
     //-----------------------------------------------------------------------
     @Test
--- a/test/java/time/tck/java/time/TCKZonedDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/TCKZonedDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -223,54 +223,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization() throws ClassNotFoundException, IOException {
-        assertSerializable(TEST_DATE_TIME);
-    }
-
-    @Test
-    public void test_serialization_format_zoneId() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(6);
-            dos.writeInt(2012); // date
-            dos.writeByte(9);
-            dos.writeByte(16);
-            dos.writeByte(22);  // time
-            dos.writeByte(17);
-            dos.writeByte(59);
-            dos.writeInt(470_000_000);
-            dos.writeByte(4);  // offset
-            dos.writeByte(7);  // zoneId
-            dos.writeUTF("Europe/London");
-        }
-        byte[] bytes = baos.toByteArray();
-        ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneId.of("Europe/London"));
-        assertSerializedBySer(zdt, bytes);
-    }
-
-    @Test
-    public void test_serialization_format_zoneOffset() throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (DataOutputStream dos = new DataOutputStream(baos) ) {
-            dos.writeByte(6);
-            dos.writeInt(2012); // date
-            dos.writeByte(9);
-            dos.writeByte(16);
-            dos.writeByte(22);  // time
-            dos.writeByte(17);
-            dos.writeByte(59);
-            dos.writeInt(470_000_000);
-            dos.writeByte(4);  // offset
-            dos.writeByte(8);  // zoneId
-            dos.writeByte(4);
-        }
-        byte[] bytes = baos.toByteArray();
-        ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneOffset.ofHours(1));
-        assertSerializedBySer(zdt, bytes);
-    }
-
-    //-----------------------------------------------------------------------
     // now()
     //-----------------------------------------------------------------------
     @Test
@@ -2049,7 +2001,7 @@
     // compare results to OffsetDateTime.until, especially wrt dates
 
     @Test(dataProvider="plusDays")
-    public void test_periodUntil_days(ZonedDateTime base, long expected, ZonedDateTime end) {
+    public void test_until_days(ZonedDateTime base, long expected, ZonedDateTime end) {
         if (base.toLocalTime().equals(end.toLocalTime()) == false) {
             return;  // avoid DST gap input values
         }
@@ -2057,27 +2009,27 @@
     }
 
     @Test(dataProvider="plusTime")
-    public void test_periodUntil_hours(ZonedDateTime base, long expected, ZonedDateTime end) {
+    public void test_until_hours(ZonedDateTime base, long expected, ZonedDateTime end) {
         assertEquals(base.until(end, HOURS), expected);
     }
 
     @Test(dataProvider="plusTime")
-    public void test_periodUntil_minutes(ZonedDateTime base, long expected, ZonedDateTime end) {
+    public void test_until_minutes(ZonedDateTime base, long expected, ZonedDateTime end) {
         assertEquals(base.until(end, MINUTES), expected * 60);
     }
 
     @Test(dataProvider="plusTime")
-    public void test_periodUntil_seconds(ZonedDateTime base, long expected, ZonedDateTime end) {
+    public void test_until_seconds(ZonedDateTime base, long expected, ZonedDateTime end) {
         assertEquals(base.until(end, SECONDS), expected * 3600);
     }
 
     @Test(dataProvider="plusTime")
-    public void test_periodUntil_nanos(ZonedDateTime base, long expected, ZonedDateTime end) {
+    public void test_until_nanos(ZonedDateTime base, long expected, ZonedDateTime end) {
         assertEquals(base.until(end, NANOS), expected * 3600_000_000_000L);
     }
 
     @Test
-    public void test_periodUntil_parisLondon() {
+    public void test_until_parisLondon() {
         ZonedDateTime midnightLondon = LocalDate.of(2012, 6, 28).atStartOfDay(ZONE_LONDON);
         ZonedDateTime midnightParis1 = LocalDate.of(2012, 6, 29).atStartOfDay(ZONE_PARIS);
         ZonedDateTime oneAm1 = LocalDateTime.of(2012, 6, 29, 1, 0).atZone(ZONE_PARIS);
@@ -2093,7 +2045,7 @@
     }
 
     @Test
-    public void test_periodUntil_gap() {
+    public void test_until_gap() {
         ZonedDateTime before = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS);
         ZonedDateTime after = TEST_PARIS_GAP_2008_03_30_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS);
 
@@ -2102,7 +2054,7 @@
     }
 
     @Test
-    public void test_periodUntil_overlap() {
+    public void test_until_overlap() {
         ZonedDateTime before = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).atZone(ZONE_PARIS);
         ZonedDateTime after = TEST_PARIS_OVERLAP_2008_10_26_02_30.withHour(0).withMinute(0).plusDays(1).atZone(ZONE_PARIS);
 
@@ -2111,17 +2063,17 @@
     }
 
     @Test(expectedExceptions=DateTimeException.class)
-    public void test_periodUntil_differentType() {
+    public void test_until_differentType() {
         TEST_DATE_TIME_PARIS.until(TEST_LOCAL_2008_06_30_11_30_59_500, DAYS);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
-    public void test_periodUntil_nullTemporal() {
+    public void test_until_nullTemporal() {
         TEST_DATE_TIME_PARIS.until(null, DAYS);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
-    public void test_periodUntil_nullUnit() {
+    public void test_until_nullUnit() {
         TEST_DATE_TIME_PARIS.until(TEST_DATE_TIME_PARIS, null);
     }
 
--- a/test/java/time/tck/java/time/chrono/CopticDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/CopticDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -297,18 +297,12 @@
     }
 
     @Override
-    public long until(Temporal endDateTime, TemporalUnit unit) {
-        if (endDateTime instanceof ChronoLocalDate == false) {
-            throw new DateTimeException("Unable to calculate period between objects 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");
-        }
+    public long until(Temporal endExclusive, TemporalUnit unit) {
+        CopticDate end = getChronology().date(endExclusive);
         if (unit instanceof ChronoUnit) {
             return LocalDate.from(this).until(end, unit);  // TODO: this is wrong
         }
-        return unit.between(this, endDateTime);
+        return unit.between(this, end);
     }
 
     @Override
@@ -354,4 +348,27 @@
                 .append(dom < 10 ? "-0" : "-").append(dom);
         return buf.toString();
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof CopticDate) {
+            CopticDate cd = (CopticDate)obj;
+            if (this.prolepticYear == cd.prolepticYear &&
+                    this.month == cd.month &&
+                    this.day == cd.day) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        long epDay = toEpochDay();
+        return getChronology().hashCode() ^ ((int) (epDay ^ (epDay >>> 32)));
+    }
+
 }
--- a/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKChronoLocalDate.java	Tue Oct 08 14:57:32 2013 -0700
@@ -306,23 +306,6 @@
         }
     }
 
-    //-----------------------------------------------------------------------
-    // Test Serialization of Calendars
-    //-----------------------------------------------------------------------
-    @Test( dataProvider="calendars")
-    public void test_ChronoSerialization(Chronology chrono) throws Exception {
-        LocalDate ref = LocalDate.of(2013, 1, 5);
-        ChronoLocalDate orginal = chrono.date(ref);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(orginal);
-        out.close();
-        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bais);
-        @SuppressWarnings("unchecked")
-        ChronoLocalDate ser = (ChronoLocalDate) in.readObject();
-        assertEquals(ser, orginal, "deserialized date is wrong");
-    }
 
     //-----------------------------------------------------------------------
     @Test(dataProvider="calendars")
--- a/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKChronoLocalDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -318,23 +318,6 @@
     }
 
     //-----------------------------------------------------------------------
-    // Test Serialization of ISO via chrono API
-    //-----------------------------------------------------------------------
-    @Test( dataProvider="calendars")
-    public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception {
-        LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3);
-        ChronoLocalDateTime<?> orginal = chrono.date(ref).atTime(ref.toLocalTime());
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(orginal);
-        out.close();
-        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bais);
-        ChronoLocalDateTime<?> ser = (ChronoLocalDateTime<?>) in.readObject();
-        assertEquals(ser, orginal, "deserialized date is wrong");
-    }
-
-    //-----------------------------------------------------------------------
     @Test(dataProvider="calendars")
     public void test_from_TemporalAccessor(Chronology chrono) {
         LocalDateTime refDateTime = LocalDateTime.of(2013, 1, 1, 12, 30);
@@ -361,6 +344,13 @@
     }
 
     //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_getChronology(Chronology chrono) {
+        ChronoLocalDateTime test = chrono.localDateTime(LocalDateTime.of(2010, 6, 30, 11, 30));
+        assertEquals(test.getChronology(), chrono);
+    }
+
+    //-----------------------------------------------------------------------
     /**
      * FixedAdjusted returns a fixed Temporal in all adjustments.
      * Construct an adjuster with the Temporal that should be returned from adjust.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/chrono/TCKChronoPeriod.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 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.chrono;
+
+import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.HOURS;
+import static java.time.temporal.ChronoUnit.MONTHS;
+import static java.time.temporal.ChronoUnit.YEARS;
+import static org.testng.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.Period;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoPeriod;
+import java.time.chrono.Chronology;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.temporal.Temporal;
+import java.time.temporal.UnsupportedTemporalTypeException;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class TCKChronoPeriod {
+
+    //-----------------------------------------------------------------------
+    // regular data factory for names and descriptions of available calendars
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "calendars")
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE}};
+    }
+
+    //-----------------------------------------------------------------------
+    // Test Serialization of Calendars
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_serialization(Chronology chrono) throws Exception {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+        out.writeObject(period);
+        out.close();
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+
+        ObjectInputStream in = new ObjectInputStream(bais);
+        ChronoPeriod ser = (ChronoPeriod) in.readObject();
+        assertEquals(ser, period, "deserialized ChronoPeriod is wrong");
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_get(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        assertEquals(period.get(YEARS), 1);
+        assertEquals(period.get(MONTHS), 2);
+        assertEquals(period.get(DAYS), 3);
+    }
+
+    @Test(dataProvider="calendars", expectedExceptions=UnsupportedTemporalTypeException.class)
+    public void test_get_unsupported(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        period.get(HOURS);
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_getUnits(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        assertEquals(period.getUnits().size(), 3);
+        assertEquals(period.getUnits().get(0), YEARS);
+        assertEquals(period.getUnits().get(1), MONTHS);
+        assertEquals(period.getUnits().get(2), DAYS);
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_getChronology(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        assertEquals(period.getChronology(), chrono);
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_isZero_isNegative(Chronology chrono) {
+        ChronoPeriod periodPositive = chrono.period(1, 2, 3);
+        assertEquals(periodPositive.isZero(), false);
+        assertEquals(periodPositive.isNegative(), false);
+
+        ChronoPeriod periodZero = chrono.period(0, 0, 0);
+        assertEquals(periodZero.isZero(), true);
+        assertEquals(periodZero.isNegative(), false);
+
+        ChronoPeriod periodNegative = chrono.period(-1, 0, 0);
+        assertEquals(periodNegative.isZero(), false);
+        assertEquals(periodNegative.isNegative(), true);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_plus(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoPeriod period2 = chrono.period(2, 3, 4);
+        ChronoPeriod result = period.plus(period2);
+        assertEquals(result, chrono.period(3, 5, 7));
+    }
+
+    @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class)
+    public void test_plus_wrongChrono(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoPeriod isoPeriod = Period.of(2, 3, 4);
+        ChronoPeriod thaiPeriod = ThaiBuddhistChronology.INSTANCE.period(2, 3, 4);
+        // one of these two will fail
+        period.plus(isoPeriod);
+        period.plus(thaiPeriod);
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_minus(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoPeriod period2 = chrono.period(2, 3, 4);
+        ChronoPeriod result = period.minus(period2);
+        assertEquals(result, chrono.period(-1, -1, -1));
+    }
+
+    @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class)
+    public void test_minus_wrongChrono(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoPeriod isoPeriod = Period.of(2, 3, 4);
+        ChronoPeriod thaiPeriod = ThaiBuddhistChronology.INSTANCE.period(2, 3, 4);
+        // one of these two will fail
+        period.minus(isoPeriod);
+        period.minus(thaiPeriod);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_addTo(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoLocalDate date = chrono.dateNow();
+        Temporal result = period.addTo(date);
+        assertEquals(result, date.plus(14, MONTHS).plus(3, DAYS));
+    }
+
+    @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class)
+    public void test_addTo_wrongChrono(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoLocalDate isoDate = LocalDate.of(2000, 1, 1);
+        ChronoLocalDate thaiDate = ThaiBuddhistChronology.INSTANCE.date(2000, 1, 1);
+        // one of these two will fail
+        period.addTo(isoDate);
+        period.addTo(thaiDate);
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_subtractFrom(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoLocalDate date = chrono.dateNow();
+        Temporal result = period.subtractFrom(date);
+        assertEquals(result, date.minus(14, MONTHS).minus(3, DAYS));
+    }
+
+    @Test(dataProvider="calendars", expectedExceptions=DateTimeException.class)
+    public void test_subtractFrom_wrongChrono(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        ChronoLocalDate isoDate = LocalDate.of(2000, 1, 1);
+        ChronoLocalDate thaiDate = ThaiBuddhistChronology.INSTANCE.date(2000, 1, 1);
+        // one of these two will fail
+        period.subtractFrom(isoDate);
+        period.subtractFrom(thaiDate);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_negated(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        assertEquals(period.negated(), chrono.period(-1, -2, -3));
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_multipliedBy(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        assertEquals(period.multipliedBy(3), chrono.period(3, 6, 9));
+    }
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_equals_equal(Chronology chrono) {
+        ChronoPeriod a1 = chrono.period(1, 2, 3);
+        ChronoPeriod a2 = chrono.period(1, 2, 3);
+        assertEquals(a1, a1);
+        assertEquals(a1, a2);
+        assertEquals(a2, a1);
+        assertEquals(a2, a2);
+        assertEquals(a1.hashCode(), a2.hashCode());
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_equals_notEqual(Chronology chrono) {
+        ChronoPeriod a = chrono.period(1, 2, 3);
+        ChronoPeriod b = chrono.period(2, 2, 3);
+        assertEquals(a.equals(b), false);
+        assertEquals(b.equals(a), false);
+        assertEquals(a.equals(""), false);
+        assertEquals(a.equals(null), false);
+    }
+
+    @Test(dataProvider="calendars")
+    public void test_toString(Chronology chrono) {
+        ChronoPeriod period = chrono.period(1, 2, 3);
+        if (period instanceof Period == false) {
+            assertEquals(period.toString(), chrono.getId() + " P1Y2M3D");
+        }
+    }
+
+}
--- a/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKChronoZonedDateTime.java	Tue Oct 08 14:57:32 2013 -0700
@@ -321,24 +321,6 @@
     }
 
     //-----------------------------------------------------------------------
-    // Test Serialization of ISO via chrono API
-    //-----------------------------------------------------------------------
-    @Test( dataProvider="calendars")
-    public void test_ChronoZonedDateTimeSerialization(Chronology chrono) throws Exception {
-        ZonedDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3).atZone(ZoneId.of("GMT+01:23"));
-        ChronoZonedDateTime<?> orginal = chrono.date(ref).atTime(ref.toLocalTime()).atZone(ref.getZone());
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(orginal);
-        out.close();
-        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bais);
-        @SuppressWarnings("unchecked")
-        ChronoZonedDateTime<?> ser = (ChronoZonedDateTime<?>) in.readObject();
-        assertEquals(ser, orginal, "deserialized date is wrong");
-    }
-
-    //-----------------------------------------------------------------------
     @Test(dataProvider="calendars")
     public void test_from_TemporalAccessor(Chronology chrono) {
         ZonedDateTime refDateTime = ZonedDateTime.of(2013, 1, 1, 12, 30, 0, 0, ZoneId.of("Europe/Paris"));
@@ -363,6 +345,13 @@
     }
 
     //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_getChronology(Chronology chrono) {
+        ChronoZonedDateTime test = chrono.zonedDateTime(ZonedDateTime.of(2010, 6, 30, 11, 30, 0, 0, ZoneOffset.UTC));
+        assertEquals(test.getChronology(), chrono);
+    }
+
+    //-----------------------------------------------------------------------
     /**
      * FixedAdjusted returns a fixed Temporal in all adjustments.
      * Construct an adjuster with the Temporal that should be returned from adjust.
--- a/test/java/time/tck/java/time/chrono/TCKChronology.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKChronology.java	Tue Oct 08 14:57:32 2013 -0700
@@ -64,7 +64,6 @@
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
-import java.util.Locale;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.ObjectInputStream;
@@ -338,20 +337,4 @@
         Chronology chrono = Chronology.of("FooFoo");
     }
 
-    //-----------------------------------------------------------------------
-    // serialization; serialize and check each calendar system
-    //-----------------------------------------------------------------------
-    @Test(dataProvider = "calendarNameAndType")
-    public void test_chronoSerializationSingleton(String id, String _calendarType) throws Exception {
-        Chronology original = Chronology.of(id);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(original);
-        out.close();
-        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bais);
-        Chronology ser = (Chronology) in.readObject();
-        assertEquals(ser, original, "Deserialized Chronology is not correct");
-    }
-
 }
--- a/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java	Tue Oct 08 14:53:14 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Copyright (c) 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.chrono;
-
-import static org.testng.Assert.assertEquals;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.PrintStream;
-import java.time.chrono.Chronology;
-import java.time.chrono.HijrahChronology;
-import java.time.chrono.IsoChronology;
-import java.time.chrono.JapaneseChronology;
-import java.time.chrono.MinguoChronology;
-import java.time.chrono.ThaiBuddhistChronology;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-public class TCKChronologySerialization {
-
-    //-----------------------------------------------------------------------
-    // regular data factory for names and descriptions of available calendars
-    //-----------------------------------------------------------------------
-    @DataProvider(name = "calendars")
-    Chronology[][] data_of_calendars() {
-        return new Chronology[][]{
-                    {HijrahChronology.INSTANCE},
-                    {IsoChronology.INSTANCE},
-                    {JapaneseChronology.INSTANCE},
-                    {MinguoChronology.INSTANCE},
-                    {ThaiBuddhistChronology.INSTANCE}};
-    }
-
-    //-----------------------------------------------------------------------
-    // Test Serialization of Calendars
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="calendars")
-    public void test_ChronoSerialization(Chronology chrono) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(chrono);
-        out.close();
-
-        byte[] bytes = baos.toByteArray();
-        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
-        ObjectInputStream in = new ObjectInputStream(bais);
-        @SuppressWarnings("unchecked")
-        Chronology ser = (Chronology) in.readObject();
-        assertEquals(ser, chrono, "deserialized Chronology is wrong");
-    }
-
-    /**
-     * Utility method to dump a byte array in a java syntax.
-     * @param bytes and array of bytes
-     * @param os the outputstream to receive the output.
-     */
-    static void dumpSerialStream(byte[] bytes, PrintStream os) {
-        os.printf("    byte[] bytes = {" );
-        final int linelen = 10;
-        for (int i = 0; i < bytes.length; i++) {
-            if (i % linelen == 0) {
-                os.printf("%n        ");
-            }
-            os.printf(" %3d,", bytes[i] & 0xff);
-            if ((i % linelen) == (linelen-1) || i == bytes.length - 1) {
-                os.printf("  /*");
-                int s = i / linelen * linelen;
-                int k = i % linelen;
-                for (int j = 0; j <= k && s + j < bytes.length; j++) {
-                    os.printf(" %c", bytes[s + j] & 0xff);
-                }
-                os.printf(" */");
-            }
-        }
-        os.printf("%n    };%n");
-    }
-
-}
--- a/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKJapaneseChronology.java	Tue Oct 08 14:57:32 2013 -0700
@@ -79,6 +79,7 @@
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.ChronoPeriod;
 import java.time.chrono.Chronology;
 import java.time.chrono.Era;
 import java.time.chrono.IsoChronology;
@@ -87,6 +88,7 @@
 import java.time.chrono.JapaneseEra;
 import java.time.chrono.MinguoChronology;
 import java.time.chrono.MinguoDate;
+import java.time.chrono.ThaiBuddhistChronology;
 import java.time.format.ResolverStyle;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
@@ -615,8 +617,8 @@
     public void test_periodUntilDate() {
         JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1);
         JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2);
-        Period period = mdate1.until(mdate2);
-        assertEquals(period, Period.of(1, 1, 1));
+        ChronoPeriod period = mdate1.until(mdate2);
+        assertEquals(period, JapaneseChronology.INSTANCE.period(1, 1, 1));
     }
 
     @Test
@@ -632,8 +634,8 @@
         JapaneseDate mdate1 = JapaneseDate.of(1970, 1, 1);
         JapaneseDate mdate2 = JapaneseDate.of(1971, 2, 2);
         MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2);
-        Period period = mdate1.until(ldate2);
-        assertEquals(period, Period.of(1, 1, 1));
+        ChronoPeriod period = mdate1.until(ldate2);
+        assertEquals(period, JapaneseChronology.INSTANCE.period(1, 1, 1));
     }
 
     //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKMinguoChronology.java	Tue Oct 08 14:57:32 2013 -0700
@@ -69,13 +69,13 @@
 import java.time.LocalTime;
 import java.time.Month;
 import java.time.OffsetDateTime;
-import java.time.Period;
 import java.time.Year;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoPeriod;
 import java.time.chrono.ChronoZonedDateTime;
 import java.time.chrono.Chronology;
 import java.time.chrono.Era;
@@ -84,8 +84,6 @@
 import java.time.chrono.MinguoChronology;
 import java.time.chrono.MinguoDate;
 import java.time.chrono.MinguoEra;
-import java.time.chrono.MinguoChronology;
-import java.time.chrono.MinguoDate;
 import java.time.chrono.ThaiBuddhistChronology;
 import java.time.chrono.ThaiBuddhistDate;
 import java.time.format.ResolverStyle;
@@ -499,8 +497,8 @@
     public void test_periodUntilDate() {
         MinguoDate mdate1 = MinguoDate.of(1970, 1, 1);
         MinguoDate mdate2 = MinguoDate.of(1971, 2, 2);
-        Period period = mdate1.until(mdate2);
-        assertEquals(period, Period.of(1, 1, 1));
+        ChronoPeriod period = mdate1.until(mdate2);
+        assertEquals(period, MinguoChronology.INSTANCE.period(1, 1, 1));
     }
 
     @Test
@@ -516,8 +514,8 @@
         MinguoDate mdate1 = MinguoDate.of(1970, 1, 1);
         MinguoDate mdate2 = MinguoDate.of(1971, 2, 2);
         ThaiBuddhistDate ldate2 = ThaiBuddhistChronology.INSTANCE.date(mdate2);
-        Period period = mdate1.until(ldate2);
-        assertEquals(period, Period.of(1, 1, 1));
+        ChronoPeriod period = mdate1.until(ldate2);
+        assertEquals(period, MinguoChronology.INSTANCE.period(1, 1, 1));
     }
 
     //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKTestServiceLoader.java	Tue Oct 08 14:57:32 2013 -0700
@@ -60,10 +60,6 @@
 
 import static org.testng.Assert.assertEquals;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.time.LocalDate;
 import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.Chronology;
@@ -78,29 +74,11 @@
 public class TCKTestServiceLoader {
 
      @Test
-     public void test_CopticServiceLoader() {
+     public void test_TestServiceLoader() {
         Chronology chrono = Chronology.of("Coptic");
         ChronoLocalDate copticDate = chrono.date(1729, 4, 27);
         LocalDate ld = LocalDate.from(copticDate);
         assertEquals(ld, LocalDate.of(2013, 1, 5), "CopticDate does not match LocalDate");
     }
 
-
-    //-----------------------------------------------------------------------
-    // Test Serialization of Loaded Coptic Calendar
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_ChronoSerialization() throws Exception {
-        Chronology chrono = Chronology.of("Coptic");
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(chrono);
-        out.close();
-        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-
-        ObjectInputStream in = new ObjectInputStream(bais);
-        @SuppressWarnings("unchecked")
-        Chronology ser = (Chronology) in.readObject();
-        assertEquals(ser, chrono, "deserialized Chronology is wrong");
-    }
 }
--- a/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/chrono/TCKThaiBuddhistChronology.java	Tue Oct 08 14:57:32 2013 -0700
@@ -72,11 +72,11 @@
 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.ChronoPeriod;
 import java.time.chrono.Chronology;
 import java.time.chrono.Era;
 import java.time.chrono.IsoChronology;
@@ -458,8 +458,8 @@
     public void test_periodUntilDate() {
         ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1);
         ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2);
-        Period period = mdate1.until(mdate2);
-        assertEquals(period, Period.of(1, 1, 1));
+        ChronoPeriod period = mdate1.until(mdate2);
+        assertEquals(period, ThaiBuddhistChronology.INSTANCE.period(1, 1, 1));
     }
 
     @Test
@@ -475,8 +475,8 @@
         ThaiBuddhistDate mdate1 = ThaiBuddhistDate.of(1, 1, 1);
         ThaiBuddhistDate mdate2 = ThaiBuddhistDate.of(2, 2, 2);
         MinguoDate ldate2 = MinguoChronology.INSTANCE.date(mdate2);
-        Period period = mdate1.until(ldate2);
-        assertEquals(period, Period.of(1, 1, 1));
+        ChronoPeriod period = mdate1.until(ldate2);
+        assertEquals(period, ThaiBuddhistChronology.INSTANCE.period(1, 1, 1));
     }
 
     //-----------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, 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.chrono.serial;
+
+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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.ObjectStreamConstants;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.JapaneseDate;
+import java.time.chrono.JapaneseEra;
+import java.time.chrono.MinguoDate;
+import java.time.chrono.ThaiBuddhistDate;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test serialization of built-in chronologies.
+ */
+@Test
+public class TCKChronoLocalDateSerialization extends AbstractTCKTest {
+
+    static final int CHRONO_TYPE = 1;            // java.time.chrono.Ser.CHRONO_TYPE
+    static final int JAPANESE_DATE_TYPE = 4;     // java.time.chrono.Ser.JAPANESE_DATE_TYPE
+    static final int HIJRAH_DATE_TYPE = 6;       // java.time.chrono.Ser.HIJRAH_DATE_TYPE
+    static final int MINGUO_DATE_TYPE = 7;       // java.time.chrono.Ser.MINGUO_DATE_TYPE
+    static final int THAIBUDDHIST_DATE_TYPE = 8; // java.time.chrono.Ser.THAIBUDDHIST_DATE_TYPE
+
+    //-----------------------------------------------------------------------
+    // Regular data factory for names and descriptions of available calendars
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "calendars")
+    Object[][] data_of_calendars() {
+        return new Object[][]{
+            {JapaneseDate.of(JapaneseEra.HEISEI, 25, 01, 05), JAPANESE_DATE_TYPE},
+            {MinguoDate.of(102, 01, 05),                      MINGUO_DATE_TYPE},
+            {ThaiBuddhistDate.of(2556, 01, 05),               THAIBUDDHIST_DATE_TYPE},
+        };
+    }
+
+
+    //-----------------------------------------------------------------------
+    // Test Serialization of Calendars
+    //-----------------------------------------------------------------------
+    @Test( dataProvider="calendars")
+    public void test_ChronoSerialization(ChronoLocalDate date, int dateType) throws Exception {
+        assertSerializable(date);
+    }
+
+    //-----------------------------------------------------------------------
+    // Test that serialization produces exact sequence of bytes
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    private void test_serialization_format(ChronoLocalDate date, int dateType) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(dateType);
+            dos.writeInt(date.get(YEAR));
+            dos.writeByte(date.get(MONTH_OF_YEAR));
+            dos.writeByte(date.get(DAY_OF_MONTH));
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(date, bytes);
+    }
+
+    //-----------------------------------------------------------------------
+    // Test HijrajDate serialization is a type, Chronology, year, month, day
+    //-----------------------------------------------------------------------
+    @Test()
+    public void test_hijrahSerialization_format() throws Exception {
+        HijrahChronology chrono = HijrahChronology.INSTANCE;
+        HijrahDate date = HijrahDate.of(1433, 10, 29);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+        // Expect the type of the HijrahDate in the stream
+        byte[] hijrahDateBytes = new byte[] {HIJRAH_DATE_TYPE};
+
+        // Literal reference to Hijrah-Umalqura Chronology
+        byte[] hijrahChronoBytes = new byte[] {
+            115, 113, 0, 126, 0, 0,                        /* p w \u0001 \u0006 s q \u0000 ~ \u0000 \u0000 */
+            119, 18, 1, 0, 15, 72, 105, 106, 114, 97,      /* w \u0012 \u0001 \u0000 \u000f H i j r a */
+            104, 45, 117, 109, 97, 108, 113, 117, 114, 97, /* h - u m a l q u r a */
+            120,                                           /*  \u001d x */
+        };
+
+        // Build the sequence that represents the data in the stream
+        baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA);
+            dos.writeByte(6);   // 6 bytes follow
+            dos.writeInt(date.get(YEAR));
+            dos.writeByte(date.get(MONTH_OF_YEAR));
+            dos.writeByte(date.get(DAY_OF_MONTH));
+            dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);
+        }
+        byte[] dateBytes = baos.toByteArray();
+
+        assertSerializedBySer(date, hijrahDateBytes, hijrahChronoBytes, dateBytes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/chrono/serial/TCKChronoLocalDateTimeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, 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.chrono.serial;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test serialization of ChronoLocalDateTime for all built-in chronologies.
+ */
+@Test
+public class TCKChronoLocalDateTimeSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    // regular data factory for available calendars
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "calendars")
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE}};
+    }
+
+    //-----------------------------------------------------------------------
+    // Test Serialization of ChronoLocalDateTime
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_ChronoLocalDateTimeSerialization(Chronology chrono) throws Exception {
+        LocalDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3);
+        ChronoLocalDateTime<?> original = chrono.date(ref).atTime(ref.toLocalTime());
+        assertSerializable(original);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/chrono/serial/TCKChronoZonedDateTimeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, 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.chrono.serial;
+
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test assertions that must be true for all built-in chronologies.
+ */
+@Test
+public class TCKChronoZonedDateTimeSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    // regular data factory for names and descriptions of available calendars
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "calendars")
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE},
+        };
+    }
+
+    //-----------------------------------------------------------------------
+    // Test Serialization of ISO via chrono API
+    //-----------------------------------------------------------------------
+    @Test( dataProvider="calendars")
+    public void test_ChronoZonedDateTimeSerialization(Chronology chrono) throws Exception {
+        ZonedDateTime ref = LocalDate.of(2013, 1, 5).atTime(12, 1, 2, 3).atZone(ZoneId.of("GMT+01:23"));
+        ChronoZonedDateTime<?> original = chrono.date(ref).atTime(ref.toLocalTime()).atZone(ref.getZone());
+        assertSerializable(original);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/chrono/serial/TCKChronologySerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 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.chrono.serial;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+
+import java.time.chrono.Chronology;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.ThaiBuddhistChronology;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import tck.java.time.AbstractTCKTest;
+
+@Test
+public class TCKChronologySerialization extends AbstractTCKTest {
+
+    static final int CHRONO_TYPE = 1;            // java.time.chrono.Ser.CHRONO_TYPE
+
+    //-----------------------------------------------------------------------
+    // Regular data factory for available calendars
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "calendars")
+    Chronology[][] data_of_calendars() {
+        return new Chronology[][]{
+                    {HijrahChronology.INSTANCE},
+                    {IsoChronology.INSTANCE},
+                    {JapaneseChronology.INSTANCE},
+                    {MinguoChronology.INSTANCE},
+                    {ThaiBuddhistChronology.INSTANCE}};
+    }
+
+    //-----------------------------------------------------------------------
+    // Test Serialization of Calendars
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    public void test_chronoSerialization(Chronology chrono) throws Exception {
+        assertSerializable(chrono);
+    }
+
+    //-----------------------------------------------------------------------
+    // Test that serialization produces exact sequence of bytes
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="calendars")
+    private void test_serializationBytes(Chronology chrono) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(CHRONO_TYPE);
+            dos.writeUTF(chrono.getId());
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(chrono, bytes);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/chrono/serial/TCKCopticSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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) 2011-2012, 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.chrono.serial;
+
+import java.io.IOException;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Chronology;
+
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Tests the serialization of ChronoLocalDate using a CopticDate.
+ */
+@Test
+public class TCKCopticSerialization extends AbstractTCKTest {
+
+    @Test
+    public void test_eraSerialization() throws IOException, ClassNotFoundException {
+        Chronology chrono = Chronology.of("Coptic");
+        ChronoLocalDate copticDate = chrono.date(1729, 4, 27);
+        assertSerializable(copticDate);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/chrono/serial/TCKEraSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,135 @@
+/*
+ * 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) 2011-2012, 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.chrono.serial;
+
+
+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;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.Era;
+import java.time.chrono.HijrahEra;
+import java.time.chrono.IsoEra;
+import java.time.chrono.JapaneseEra;
+import java.time.chrono.MinguoEra;
+import java.time.chrono.ThaiBuddhistEra;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Tests the built-in Eras are serializable.
+ * Note that the serialized form of IsoEra, MinguoEra, ThaiBuddhistEra,
+ * and HijrahEra are defined and provided by Enum.
+ * The serialized form of these types are not tested, only that they are
+ * serializable.
+ */
+@Test
+public class TCKEraSerialization extends AbstractTCKTest {
+
+    static final int JAPANESE_ERA_TYPE = 5;     // java.time.chrono.Ser.JAPANESE_ERA
+
+
+    //-----------------------------------------------------------------------
+    // Regular data factory for the available Eras
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "Eras")
+    Era[][] data_of_calendars() {
+        return new Era[][] {
+                    {HijrahEra.AH},
+                    {IsoEra.BCE},
+                    {IsoEra.CE},
+                    {MinguoEra.BEFORE_ROC},
+                    {MinguoEra.ROC},
+                    {ThaiBuddhistEra.BEFORE_BE},
+                    {ThaiBuddhistEra.BE},
+        };
+    }
+
+    @Test(dataProvider="Eras")
+    public void test_eraSerialization(Era era) throws IOException, ClassNotFoundException {
+        assertSerializableSame(era);
+    }
+
+    //-----------------------------------------------------------------------
+    // Test JapaneseEra serialization produces exact sequence of bytes
+    //-----------------------------------------------------------------------
+    @Test
+    private void test_JapaneseErasSerialization() throws Exception {
+        for (JapaneseEra era : JapaneseEra.values()) {
+            assertSerializableSame(era);
+
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try (DataOutputStream dos = new DataOutputStream(baos) ) {
+                dos.writeByte(JAPANESE_ERA_TYPE);
+                dos.writeByte(era.getValue());
+            }
+            byte[] bytes = baos.toByteArray();
+            assertSerializedBySer(era, bytes);
+        }
+    }
+
+}
--- a/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/format/TCKDateTimeParseResolver.java	Tue Oct 08 14:57:32 2013 -0700
@@ -90,20 +90,33 @@
 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
 import static java.time.temporal.ChronoField.YEAR;
 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
+import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.FOREVER;
+import static java.time.temporal.ChronoUnit.NANOS;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
 
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.chrono.Chronology;
+import java.time.chrono.ThaiBuddhistChronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
 import java.time.format.ResolverStyle;
+import java.time.temporal.ChronoUnit;
 import java.time.temporal.IsoFields;
+import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.ValueRange;
+import java.util.Map;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -872,4 +885,210 @@
         }
     }
 
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_fieldResolvesToLocalTime() {
+        TemporalField field = new TemporalField() {
+            @Override
+            public TemporalUnit getBaseUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalUnit getRangeUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange range() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isDateBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isTimeBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isSupportedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public long getFrom(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalAccessor resolve(
+                    Map<TemporalField, Long> fieldValues, Chronology chronology,
+                    ZoneId zone, ResolverStyle resolverStyle) {
+                return LocalTime.MIDNIGHT.plusNanos(fieldValues.remove(this));
+            }
+        };
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter();
+        TemporalAccessor accessor = f.parse("1234567890");
+        assertEquals(accessor.query(TemporalQuery.localDate()), null);
+        assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.of(0, 0, 1, 234_567_890));
+    }
+
+    @Test
+    public void test_fieldResolvesToChronoLocalDateTime() {
+        TemporalField field = new TemporalField() {
+            @Override
+            public TemporalUnit getBaseUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalUnit getRangeUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange range() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isDateBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isTimeBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isSupportedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public long getFrom(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalAccessor resolve(
+                    Map<TemporalField, Long> fieldValues, Chronology chronology,
+                    ZoneId zone, ResolverStyle resolverStyle) {
+                fieldValues.remove(this);
+                return LocalDateTime.of(2010, 6, 30, 12, 30);
+            }
+        };
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter();
+        TemporalAccessor accessor = f.parse("1234567890");
+        assertEquals(accessor.query(TemporalQuery.localDate()), LocalDate.of(2010, 6, 30));
+        assertEquals(accessor.query(TemporalQuery.localTime()), LocalTime.of(12, 30));
+    }
+
+    @Test(expectedExceptions = DateTimeParseException.class)
+    public void test_fieldResolvesWrongChrono() {
+        TemporalField field = new TemporalField() {
+            @Override
+            public TemporalUnit getBaseUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalUnit getRangeUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange range() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isDateBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isTimeBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isSupportedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public long getFrom(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalAccessor resolve(
+                    Map<TemporalField, Long> fieldValues, Chronology chronology,
+                    ZoneId zone, ResolverStyle resolverStyle) {
+                return ThaiBuddhistChronology.INSTANCE.dateNow();
+            }
+        };
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter();
+        f.parse("1234567890");
+    }
+
+    @Test(expectedExceptions = DateTimeParseException.class)
+    public void test_fieldResolvesWrongZone() {
+        TemporalField field = new TemporalField() {
+            @Override
+            public TemporalUnit getBaseUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalUnit getRangeUnit() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange range() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isDateBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isTimeBased() {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public boolean isSupportedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public long getFrom(TemporalAccessor temporal) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+                throw new UnsupportedOperationException();
+            }
+            @Override
+            public TemporalAccessor resolve(
+                    Map<TemporalField, Long> fieldValues, Chronology chronology,
+                    ZoneId zone, ResolverStyle resolverStyle) {
+                return ZonedDateTime.of(2010, 6, 30, 12, 30, 0, 0, ZoneId.of("Europe/Paris"));
+            }
+        };
+        DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(field).toFormatter().withZone(ZoneId.of("Europe/London"));
+        f.parse("1234567890");
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKClockSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012 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.serial;
+
+
+import java.io.IOException;
+import java.time.Clock;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+import org.testng.annotations.Test;
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test system and offset clocks serialization.
+ */
+@Test
+public class TCKClockSerialization extends AbstractTCKTest {
+
+    private static final ZoneId MOSCOW = ZoneId.of("Europe/Moscow");
+    private static final ZoneId PARIS = ZoneId.of("Europe/Paris");
+
+    private static final Duration AMOUNT = Duration.ofSeconds(2);
+    private static final ZonedDateTime ZDT = LocalDateTime.of(2008, 6, 30, 11, 30, 10, 500).atZone(ZoneOffset.ofHours(2));
+    private static final Instant INSTANT = ZDT.toInstant();
+
+    //-----------------------------------------------------------------------
+    public void test_systemClockSerializable() throws IOException, ClassNotFoundException {
+        assertSerializable(Clock.systemUTC());
+        assertSerializable(Clock.systemDefaultZone());
+        assertSerializable(Clock.system(PARIS));
+    }
+
+    //-----------------------------------------------------------------------
+    public void test_offsetClockSerializable() throws IOException, ClassNotFoundException {
+        assertSerializable(Clock.offset(Clock.system(PARIS), AMOUNT));
+    }
+
+    //-----------------------------------------------------------------------
+    public void test_tickClockSerializable() throws IOException, ClassNotFoundException {
+        assertSerializable(Clock.tickSeconds(PARIS));
+        assertSerializable(Clock.tickMinutes(MOSCOW));
+        assertSerializable(Clock.tick(Clock.fixed(INSTANT, PARIS), AMOUNT));
+    }
+
+    //-----------------------------------------------------------------------
+    public void test_fixedClockSerializable() throws IOException, ClassNotFoundException {
+        assertSerializable(Clock.fixed(INSTANT, ZoneOffset.UTC));
+        assertSerializable(Clock.fixed(INSTANT, PARIS));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKDurationSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.
+ */
+
+/*
+ * 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) 2007-2012, 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.serial;
+
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+import java.time.Duration;
+
+/**
+ * Test Duration serialization.
+ */
+@Test
+public class TCKDurationSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_interfaces() {
+        assertTrue(Serializable.class.isAssignableFrom(Duration.class));
+        assertTrue(Comparable.class.isAssignableFrom(Duration.class));
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(Duration.ofHours(5));
+        assertSerializable(Duration.ofHours(0));
+        assertSerializable(Duration.ofHours(-5));
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(1);
+            dos.writeLong(654321);
+            dos.writeInt(123456789);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(Duration.ofSeconds(654321, 123456789), bytes);
+    }
+
+    //-----------------------------------------------------------------------
+    // serialization
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_deserializationSingleton() throws Exception {
+        assertSerializableSame(Duration.ZERO);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKInstantSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2007-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.Instant;
+
+/**
+ * Test Instant serialization.
+ */
+@Test
+public class TCKInstantSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(Instant.ofEpochMilli(134l));
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(2);
+            dos.writeLong(654321);
+            dos.writeInt(123456789);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(Instant.ofEpochSecond(654321, 123456789), bytes);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKLocalDateSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2007-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.LocalDate;
+
+/**
+ * Test LocalDate serialization.
+ */
+@Test
+public class TCKLocalDateSerialization extends AbstractTCKTest {
+
+    private LocalDate TEST_2007_07_15;
+
+    @BeforeMethod
+    public void setUp() {
+        TEST_2007_07_15 = LocalDate.of(2007, 7, 15);
+    }
+
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(TEST_2007_07_15);
+        assertSerializable(LocalDate.MIN);
+        assertSerializable(LocalDate.MAX);
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(3);
+            dos.writeInt(2012);
+            dos.writeByte(9);
+            dos.writeByte(16);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(LocalDate.of(2012, 9, 16), bytes);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKLocalDateTimeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.LocalDateTime;
+
+/**
+ * Test serialization of LocalDateTime.
+ */
+@Test
+public class TCKLocalDateTimeSerialization extends AbstractTCKTest {
+
+    private LocalDateTime TEST_2007_07_15_12_30_40_987654321 = LocalDateTime.of(2007, 7, 15, 12, 30, 40, 987654321);
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(TEST_2007_07_15_12_30_40_987654321);
+        assertSerializable(LocalDateTime.MIN);
+        assertSerializable(LocalDateTime.MAX);
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(5);
+            dos.writeInt(2012);
+            dos.writeByte(9);
+            dos.writeByte(16);
+            dos.writeByte(22);
+            dos.writeByte(17);
+            dos.writeByte(59);
+            dos.writeInt(459_000_000);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(LocalDateTime.of(2012, 9, 16, 22, 17, 59, 459_000_000), bytes);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKLocalTimeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2007-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.LocalTime;
+
+/**
+ * Test LocalTime serialization.
+ */
+@Test
+public class TCKLocalTimeSerialization extends AbstractTCKTest {
+
+
+    private LocalTime TEST_12_30_40_987654321;
+
+
+    @BeforeMethod
+    public void setUp() {
+        TEST_12_30_40_987654321 = LocalTime.of(12, 30, 40, 987654321);
+    }
+
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(TEST_12_30_40_987654321);
+        assertSerializable(LocalTime.MIN);
+        assertSerializable(LocalTime.MAX);
+    }
+
+    @Test
+    public void test_serialization_format_h() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(4);
+            dos.writeByte(-1 - 22);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(LocalTime.of(22, 0), bytes);
+    }
+
+    @Test
+    public void test_serialization_format_hm() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(4);
+            dos.writeByte(22);
+            dos.writeByte(-1 - 17);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(LocalTime.of(22, 17), bytes);
+    }
+
+    @Test
+    public void test_serialization_format_hms() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(4);
+            dos.writeByte(22);
+            dos.writeByte(17);
+            dos.writeByte(-1 - 59);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(LocalTime.of(22, 17, 59), bytes);
+    }
+
+    @Test
+    public void test_serialization_format_hmsn() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(4);
+            dos.writeByte(22);
+            dos.writeByte(17);
+            dos.writeByte(59);
+            dos.writeInt(459_000_000);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(LocalTime.of(22, 17, 59, 459_000_000), bytes);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKMonthDaySerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.time.MonthDay;
+
+/**
+ * Test MonthDay serialization.
+ */
+@Test
+public class TCKMonthDaySerialization extends AbstractTCKTest {
+
+    private MonthDay TEST_07_15;
+
+    @BeforeMethod
+    public void setUp() {
+        TEST_07_15 = MonthDay.of(7, 15);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws ClassNotFoundException, IOException {
+        assertSerializable(TEST_07_15);
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(13);       // java.time.temporal.Ser.MONTH_DAY_TYPE
+            dos.writeByte(9);
+            dos.writeByte(16);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(MonthDay.of(9, 16), bytes);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKOffsetDateTimeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+
+/**
+ * Test OffsetDateTime serialization.
+ */
+@Test
+public class TCKOffsetDateTimeSerialization extends AbstractTCKTest {
+
+    private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
+    private OffsetDateTime TEST_2008_6_30_11_30_59_000000500;
+
+    @BeforeMethod
+    public void setUp() {
+        TEST_2008_6_30_11_30_59_000000500 = OffsetDateTime.of(2008, 6, 30, 11, 30, 59, 500, OFFSET_PONE);
+    }
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(TEST_2008_6_30_11_30_59_000000500);
+        assertSerializable(OffsetDateTime.MIN);
+        assertSerializable(OffsetDateTime.MAX);
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(10);       // java.time.Ser.OFFSET_DATE_TIME_TYPE
+        }
+        byte[] bytes = baos.toByteArray();
+        ByteArrayOutputStream baosDateTime = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baosDateTime) ) {
+            dos.writeByte(5);
+            dos.writeInt(2012);
+            dos.writeByte(9);
+            dos.writeByte(16);
+            dos.writeByte(22);
+            dos.writeByte(17);
+            dos.writeByte(59);
+            dos.writeInt(464_000_000);
+        }
+        byte[] bytesDateTime = baosDateTime.toByteArray();
+        ByteArrayOutputStream baosOffset = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baosOffset) ) {
+            dos.writeByte(8);
+            dos.writeByte(4);  // quarter hours stored: 3600 / 900
+        }
+        byte[] bytesOffset = baosOffset.toByteArray();
+        LocalDateTime ldt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 464_000_000);
+        assertSerializedBySer(OffsetDateTime.of(ldt, ZoneOffset.ofHours(1)), bytes, bytesDateTime, bytesOffset);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKOffsetTimeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
+
+/**
+ * Test OffsetTime serialization.
+ */
+@Test
+public class TCKOffsetTimeSerialization extends AbstractTCKTest {
+
+    private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
+    private OffsetTime TEST_11_30_59_500_PONE;
+
+    @BeforeMethod
+    public void setUp() {
+        TEST_11_30_59_500_PONE = OffsetTime.of(11, 30, 59, 500, OFFSET_PONE);
+    }
+
+
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(TEST_11_30_59_500_PONE);
+        assertSerializable(OffsetTime.MIN);
+        assertSerializable(OffsetTime.MAX);
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(9);       // java.time.Ser.OFFSET_TIME_TYPE
+        }
+        byte[] bytes = baos.toByteArray();
+        ByteArrayOutputStream baosTime = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baosTime) ) {
+            dos.writeByte(4);
+            dos.writeByte(22);
+            dos.writeByte(17);
+            dos.writeByte(59);
+            dos.writeInt(464_000_000);
+        }
+        byte[] bytesTime = baosTime.toByteArray();
+        ByteArrayOutputStream baosOffset = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baosOffset) ) {
+            dos.writeByte(8);
+            dos.writeByte(4);  // quarter hours stored: 3600 / 900
+        }
+        byte[] bytesOffset = baosOffset.toByteArray();
+        assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes,
+                bytesTime, bytesOffset);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKPeriodSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.time.Period;
+
+/**
+ * Test serialization of Period.
+ */
+@Test
+public class TCKPeriodSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(Period.ZERO);
+        assertSerializable(Period.ofDays(1));
+        assertSerializable(Period.of(1, 2, 3));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKYearMonthSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.time.YearMonth;
+
+/**
+ * Test serialization of YearMonth.
+ */
+@Test
+public class TCKYearMonthSerialization extends AbstractTCKTest {
+
+    private YearMonth TEST_2008_06;
+
+    @BeforeMethod
+    public void setUp() {
+        TEST_2008_06 = YearMonth.of(2008, 6);
+    }
+
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws IOException, ClassNotFoundException {
+        assertSerializable(TEST_2008_06);
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(12);       // java.time.temporal.Ser.YEAR_MONTH_TYPE
+            dos.writeInt(2012);
+            dos.writeByte(9);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(YearMonth.of(2012, 9), bytes);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKYearSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.Year;
+
+/**
+ * Test Year serialization.
+ */
+@Test
+public class TCKYearSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(Year.of(2));
+        assertSerializable(Year.of(0));
+        assertSerializable(Year.of(-2));
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(11);       // java.time.temporal.Ser.YEAR_TYPE
+            dos.writeInt(2012);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(Year.of(2012), bytes);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.time.DateTimeException;
+import java.time.ZoneId;
+import java.time.zone.ZoneRulesException;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+/**
+ * Test serialization of ZoneId.
+ */
+@Test
+public class TCKZoneIdSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(ZoneId.of("Europe/London"));
+        assertSerializable(ZoneId.of("America/Chicago"));
+    }
+
+    @Test
+    public void test_serialization_format() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(7);
+            dos.writeUTF("Europe/London");
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(ZoneId.of("Europe/London"), bytes);
+    }
+
+    @Test
+    public void test_deserialization_lenient_characters() throws Exception {
+        // an ID can be loaded without validation during deserialization
+        String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-";
+        ZoneId deser = deserialize(id);
+        // getId, equals, hashCode, toString and normalized are OK
+        assertEquals(deser.getId(), id);
+        assertEquals(deser.toString(), id);
+        assertEquals(deser, deser);
+        assertEquals(deser.hashCode(), deser.hashCode());
+        assertEquals(deser.normalized(), deser);
+        // getting the rules is not
+        try {
+            deser.getRules();
+            fail();
+        } catch (ZoneRulesException ex) {
+            // expected
+        }
+    }
+
+    @Test(expectedExceptions=DateTimeException.class)
+    public void test_deserialization_lenient_badCharacters() throws Exception {
+        // an ID can be loaded without validation during deserialization
+        // but there is a check to ensure the ID format is valid
+        deserialize("|!?");
+    }
+
+    @Test(dataProvider="offsetBasedValid")
+    public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception {
+        ZoneId deserialized = deserialize(input);
+        assertEquals(deserialized, ZoneId.of(input));
+        assertEquals(deserialized, ZoneId.of(resolvedId));
+    }
+
+    @Test(dataProvider="offsetBasedValidPrefix")
+    public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId, String offsetId) throws Exception {
+        ZoneId deserialized = deserialize("UTC" + input);
+        assertEquals(deserialized, ZoneId.of("UTC" + input));
+        assertEquals(deserialized, ZoneId.of("UTC" + resolvedId));
+    }
+
+    @Test(dataProvider="offsetBasedValidPrefix")
+    public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId, String offsetId) throws Exception {
+        ZoneId deserialized = deserialize("GMT" + input);
+        assertEquals(deserialized, ZoneId.of("GMT" + input));
+        assertEquals(deserialized, ZoneId.of("GMT" + resolvedId));
+    }
+
+    @Test(dataProvider="offsetBasedValidPrefix")
+    public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId, String offsetId) throws Exception {
+        ZoneId deserialized = deserialize("UT" + input);
+        assertEquals(deserialized, ZoneId.of("UT" + input));
+        assertEquals(deserialized, ZoneId.of("UT" + resolvedId));
+    }
+
+    private ZoneId deserialize(String id) throws Exception {
+        String serClass = ZoneId.class.getPackage().getName() + ".Ser";
+        Class<?> serCls = Class.forName(serClass);
+        Field field = serCls.getDeclaredField("serialVersionUID");
+        field.setAccessible(true);
+        long serVer = (Long) field.get(null);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos)) {
+            dos.writeShort(ObjectStreamConstants.STREAM_MAGIC);
+            dos.writeShort(ObjectStreamConstants.STREAM_VERSION);
+            dos.writeByte(ObjectStreamConstants.TC_OBJECT);
+            dos.writeByte(ObjectStreamConstants.TC_CLASSDESC);
+            dos.writeUTF(serClass);
+            dos.writeLong(serVer);
+            dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA);
+            dos.writeShort(0);  // number of fields
+            dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);  // end of classdesc
+            dos.writeByte(ObjectStreamConstants.TC_NULL);  // no superclasses
+            dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA);
+            dos.writeByte(1 + 2 + id.length());  // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF)
+            dos.writeByte(7);  // ZoneId
+            dos.writeUTF(id);
+            dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);  // end of blockdata
+        }
+        ZoneId deser = null;
+        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
+            deser = (ZoneId) ois.readObject();
+        }
+        return deser;
+    }
+
+    //-----------------------------------------------------------------------
+    // regular factory and .normalized()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="offsetBasedValid")
+    Object[][] data_offsetBasedValid() {
+        return new Object[][] {
+                {"Z", "Z"},
+                {"+0", "Z"},
+                {"-0", "Z"},
+                {"+00", "Z"},
+                {"+0000", "Z"},
+                {"+00:00", "Z"},
+                {"+000000", "Z"},
+                {"+00:00:00", "Z"},
+                {"-00", "Z"},
+                {"-0000", "Z"},
+                {"-00:00", "Z"},
+                {"-000000", "Z"},
+                {"-00:00:00", "Z"},
+                {"+5", "+05:00"},
+                {"+01", "+01:00"},
+                {"+0100", "+01:00"},
+                {"+01:00", "+01:00"},
+                {"+010000", "+01:00"},
+                {"+01:00:00", "+01:00"},
+                {"+12", "+12:00"},
+                {"+1234", "+12:34"},
+                {"+12:34", "+12:34"},
+                {"+123456", "+12:34:56"},
+                {"+12:34:56", "+12:34:56"},
+                {"-02", "-02:00"},
+                {"-5", "-05:00"},
+                {"-0200", "-02:00"},
+                {"-02:00", "-02:00"},
+                {"-020000", "-02:00"},
+                {"-02:00:00", "-02:00"},
+        };
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="offsetBasedValidPrefix")
+    Object[][] data_offsetBasedValidPrefix() {
+        return new Object[][] {
+                {"", "", "Z"},
+                {"+0", "", "Z"},
+                {"-0", "", "Z"},
+                {"+00", "", "Z"},
+                {"+0000", "", "Z"},
+                {"+00:00", "", "Z"},
+                {"+000000", "", "Z"},
+                {"+00:00:00", "", "Z"},
+                {"-00", "", "Z"},
+                {"-0000", "", "Z"},
+                {"-00:00", "", "Z"},
+                {"-000000", "", "Z"},
+                {"-00:00:00", "", "Z"},
+                {"+5", "+05:00", "+05:00"},
+                {"+01", "+01:00", "+01:00"},
+                {"+0100", "+01:00", "+01:00"},
+                {"+01:00", "+01:00", "+01:00"},
+                {"+010000", "+01:00", "+01:00"},
+                {"+01:00:00", "+01:00", "+01:00"},
+                {"+12", "+12:00", "+12:00"},
+                {"+1234", "+12:34", "+12:34"},
+                {"+12:34", "+12:34", "+12:34"},
+                {"+123456", "+12:34:56", "+12:34:56"},
+                {"+12:34:56", "+12:34:56", "+12:34:56"},
+                {"-02", "-02:00", "-02:00"},
+                {"-5", "-05:00", "-05:00"},
+                {"-0200", "-02:00", "-02:00"},
+                {"-02:00", "-02:00", "-02:00"},
+                {"-020000", "-02:00", "-02:00"},
+                {"-02:00:00", "-02:00", "-02:00"},
+        };
+    }
+
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKZoneOffsetSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.time.ZoneOffset;
+
+/**
+ * Test serialization of ZoneOffset.
+ */
+@Test
+public class TCKZoneOffsetSerialization extends AbstractTCKTest {
+
+
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws Exception {
+        assertSerializable(ZoneOffset.of("+01:30"));
+    }
+
+    @Test
+    public void test_serialization_format_quarterPositive() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(8);
+            dos.writeByte(6);  // stored as quarter hours
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(ZoneOffset.ofHoursMinutes(1, 30), bytes);
+    }
+
+    @Test
+    public void test_serialization_format_quarterNegative() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(8);
+            dos.writeByte(-10);  // stored as quarter hours
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(ZoneOffset.ofHoursMinutes(-2, -30), bytes);
+    }
+
+    @Test
+    public void test_serialization_format_full() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(8);
+            dos.writeByte(127);
+            dos.writeInt(53265);
+        }
+        byte[] bytes = baos.toByteArray();
+        assertSerializedBySer(ZoneOffset.ofTotalSeconds(53265), bytes);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/serial/TCKZonedDateTimeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.serial;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+/**
+ * Test serialization of ZonedDateTime.
+ */
+@Test
+public class TCKZonedDateTimeSerialization extends AbstractTCKTest {
+
+    private static final ZoneOffset OFFSET_0100 = ZoneOffset.ofHours(1);
+    private static final ZoneId ZONE_0100 = OFFSET_0100;
+    private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
+    private LocalDateTime TEST_LOCAL_2008_06_30_11_30_59_500;
+    private ZonedDateTime TEST_DATE_TIME;
+
+
+    @BeforeMethod
+    public void setUp() {
+        TEST_LOCAL_2008_06_30_11_30_59_500 = LocalDateTime.of(2008, 6, 30, 11, 30, 59, 500);
+        TEST_DATE_TIME = ZonedDateTime.of(TEST_LOCAL_2008_06_30_11_30_59_500, ZONE_0100);
+    }
+
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization() throws ClassNotFoundException, IOException {
+        assertSerializable(TEST_DATE_TIME);
+    }
+
+    @Test
+    public void test_serialization_format_zoneId() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(6);
+            dos.writeInt(2012); // date
+            dos.writeByte(9);
+            dos.writeByte(16);
+            dos.writeByte(22);  // time
+            dos.writeByte(17);
+            dos.writeByte(59);
+            dos.writeInt(470_000_000);
+            dos.writeByte(4);  // offset
+            dos.writeByte(7);  // zoneId
+            dos.writeUTF("Europe/London");
+        }
+        byte[] bytes = baos.toByteArray();
+        ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneId.of("Europe/London"));
+        assertSerializedBySer(zdt, bytes);
+    }
+
+    @Test
+    public void test_serialization_format_zoneOffset() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DataOutputStream dos = new DataOutputStream(baos) ) {
+            dos.writeByte(6);
+            dos.writeInt(2012); // date
+            dos.writeByte(9);
+            dos.writeByte(16);
+            dos.writeByte(22);  // time
+            dos.writeByte(17);
+            dos.writeByte(59);
+            dos.writeInt(470_000_000);
+            dos.writeByte(4);  // offset
+            dos.writeByte(8);  // zoneId
+            dos.writeByte(4);
+        }
+        byte[] bytes = baos.toByteArray();
+        ZonedDateTime zdt = LocalDateTime.of(2012, 9, 16, 22, 17, 59, 470_000_000).atZone(ZoneOffset.ofHours(1));
+        assertSerializedBySer(zdt, bytes);
+    }
+
+}
--- a/test/java/time/tck/java/time/temporal/TCKIsoFields.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/temporal/TCKIsoFields.java	Tue Oct 08 14:57:32 2013 -0700
@@ -70,11 +70,13 @@
 
 import java.time.DayOfWeek;
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DateTimeParseException;
 import java.time.format.ResolverStyle;
 import java.time.temporal.IsoFields;
+import java.time.temporal.Temporal;
 import java.time.temporal.ValueRange;
 
 import org.testng.annotations.DataProvider;
@@ -276,14 +278,21 @@
                 {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 12, 31), -4},
                 {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 2), -4},
                 {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 1), -5},
+
+                {LocalDate.of(2000, 1, 1), LocalDateTime.of(2001, 4, 5, 0, 0), 5},
         };
     }
 
     @Test(dataProvider="quartersBetween")
-    public void test_quarters_between(LocalDate start, LocalDate end, long expected) {
+    public void test_quarters_between(LocalDate start, Temporal end, long expected) {
         assertEquals(IsoFields.QUARTER_YEARS.between(start, end), expected);
     }
 
+    @Test(dataProvider="quartersBetween")
+    public void test_quarters_between_until(LocalDate start, Temporal end, long expected) {
+        assertEquals(start.until(end, IsoFields.QUARTER_YEARS), expected);
+    }
+
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
--- a/test/java/time/tck/java/time/temporal/TCKJulianFields.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/temporal/TCKJulianFields.java	Tue Oct 08 14:57:32 2013 -0700
@@ -76,7 +76,7 @@
 import tck.java.time.AbstractTCKTest;
 
 /**
- * Test.
+ * Test Julian Fields.
  */
 @Test
 public class TCKJulianFields extends AbstractTCKTest {
@@ -86,16 +86,6 @@
     private static final LocalDate NOV12_1945 = LocalDate.of(1945, 11, 12);
     private static final LocalDate JAN01_0001 = LocalDate.of(1, 1, 1);
 
-    //-----------------------------------------------------------------------
-    @DataProvider(name="julian_fields")
-    Object[][] julian_samples() {
-        return new Object[][] {
-            {JulianFields.JULIAN_DAY},
-            {JulianFields.MODIFIED_JULIAN_DAY},
-            {JulianFields.RATA_DIE},
-        };
-    }
-
     @DataProvider(name="samples")
     Object[][] data_samples() {
         return new Object[][] {
@@ -122,11 +112,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @Test(dataProvider="julian_fields")
-    public void test_serializable(TemporalField field) throws IOException, ClassNotFoundException {
-        assertSerializable(field);
-    }
-
     public void test_basics() {
         assertEquals(JulianFields.JULIAN_DAY.isDateBased(), true);
         assertEquals(JulianFields.JULIAN_DAY.isTimeBased(), false);
--- a/test/java/time/tck/java/time/temporal/TCKWeekFields.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/temporal/TCKWeekFields.java	Tue Oct 08 14:57:32 2013 -0700
@@ -713,12 +713,6 @@
         }
     }
 
-    //-----------------------------------------------------------------------
-    @Test(dataProvider="weekFields")
-    public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException {
-        WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays);
-        assertSerializableSame(weekDef);  // spec state singleton
-    }
 
     //-----------------------------------------------------------------------
     @DataProvider(name="weekFields")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/temporal/serial/TCKChronoFieldSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, 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.temporal.serial;
+
+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;
+import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
+import static java.time.temporal.ChronoField.AMPM_OF_DAY;
+import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
+import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.DAY_OF_YEAR;
+import static java.time.temporal.ChronoField.EPOCH_DAY;
+import static java.time.temporal.ChronoField.HOUR_OF_AMPM;
+import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.MICRO_OF_DAY;
+import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
+import static java.time.temporal.ChronoField.MILLI_OF_DAY;
+import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
+import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
+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_DAY;
+import static java.time.temporal.ChronoField.NANO_OF_SECOND;
+import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
+import static java.time.temporal.ChronoField.SECOND_OF_DAY;
+import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
+import static java.time.temporal.ChronoField.YEAR;
+import static java.time.temporal.ChronoField.YEAR_OF_ERA;
+import static java.time.temporal.ChronoField.ERA;
+
+import java.io.IOException;
+import java.time.temporal.ChronoField;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test serialization of ChronoField.
+ */
+@Test
+public class TCKChronoFieldSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    // List of Fields
+    //-----------------------------------------------------------------------
+    @DataProvider(name="fieldBased")
+    Object[][] data_fieldBased() {
+        return new Object[][] {
+                {DAY_OF_WEEK},
+                {ALIGNED_DAY_OF_WEEK_IN_MONTH},
+                {ALIGNED_DAY_OF_WEEK_IN_YEAR},
+                {DAY_OF_MONTH},
+                {DAY_OF_YEAR},
+                {EPOCH_DAY},
+                {ALIGNED_WEEK_OF_MONTH},
+                {ALIGNED_WEEK_OF_YEAR},
+                {MONTH_OF_YEAR},
+                {PROLEPTIC_MONTH},
+                {YEAR_OF_ERA},
+                {YEAR},
+                {ERA},
+
+                {AMPM_OF_DAY},
+                {CLOCK_HOUR_OF_DAY},
+                {HOUR_OF_DAY},
+                {CLOCK_HOUR_OF_AMPM},
+                {HOUR_OF_AMPM},
+                {MINUTE_OF_DAY},
+                {MINUTE_OF_HOUR},
+                {SECOND_OF_DAY},
+                {SECOND_OF_MINUTE},
+                {MILLI_OF_DAY},
+                {MILLI_OF_SECOND},
+                {MICRO_OF_DAY},
+                {MICRO_OF_SECOND},
+                {NANO_OF_DAY},
+                {NANO_OF_SECOND},
+        };
+    }
+
+    @Test(dataProvider = "fieldBased")
+    public void test_fieldSerializable(ChronoField field) throws IOException, ClassNotFoundException {
+        assertSerializableSame(field);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/temporal/serial/TCKChronoUnitSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, 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.temporal.serial;
+
+import static java.time.temporal.ChronoUnit.CENTURIES;
+import static java.time.temporal.ChronoUnit.DAYS;
+import static java.time.temporal.ChronoUnit.DECADES;
+import static java.time.temporal.ChronoUnit.ERAS;
+import static java.time.temporal.ChronoUnit.FOREVER;
+import static java.time.temporal.ChronoUnit.HALF_DAYS;
+import static java.time.temporal.ChronoUnit.HOURS;
+import static java.time.temporal.ChronoUnit.MICROS;
+import static java.time.temporal.ChronoUnit.MILLENNIA;
+import static java.time.temporal.ChronoUnit.MILLIS;
+import static java.time.temporal.ChronoUnit.MINUTES;
+import static java.time.temporal.ChronoUnit.MONTHS;
+import static java.time.temporal.ChronoUnit.NANOS;
+import static java.time.temporal.ChronoUnit.SECONDS;
+import static java.time.temporal.ChronoUnit.WEEKS;
+import static java.time.temporal.ChronoUnit.YEARS;
+
+import java.io.IOException;
+import java.time.temporal.ChronoUnit;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test.
+ */
+@Test
+public class TCKChronoUnitSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    // ChronoUnits
+    //-----------------------------------------------------------------------
+    @DataProvider(name="chronoUnit")
+    Object[][] data_chronoUnit() {
+        return new Object[][] {
+                {FOREVER},
+                {ERAS},
+                {MILLENNIA},
+                {CENTURIES},
+                {DECADES},
+                {YEARS},
+                {MONTHS},
+                {WEEKS},
+                {DAYS},
+
+                {HALF_DAYS},
+                {HOURS},
+                {MINUTES},
+                {SECONDS},
+                {MICROS},
+                {MILLIS},
+                {NANOS},
+
+        };
+    }
+
+    @Test(dataProvider = "chronoUnit")
+    public void test_unitType(ChronoUnit unit) throws IOException, ClassNotFoundException {
+        assertSerializableSame(unit);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/temporal/serial/TCKJulianFieldsSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.temporal.serial;
+
+import java.io.IOException;
+import java.time.temporal.JulianFields;
+import java.time.temporal.TemporalField;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test serialization of JulianFields
+ */
+@Test
+public class TCKJulianFieldsSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="julian_fields")
+    Object[][] julian_samples() {
+        return new Object[][] {
+            {JulianFields.JULIAN_DAY},
+            {JulianFields.MODIFIED_JULIAN_DAY},
+            {JulianFields.RATA_DIE},
+        };
+    }
+
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="julian_fields")
+    public void test_serializable(TemporalField field) throws IOException, ClassNotFoundException {
+        assertSerializable(field);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/temporal/serial/TCKValueRangeSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2009-2012, 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.temporal.serial;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.time.temporal.ValueRange;
+
+import org.testng.annotations.Test;
+
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test serialization of ValueRange.
+ */
+@Test
+public class TCKValueRangeSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    // Serialization
+    //-----------------------------------------------------------------------
+    public void test_serialization() throws Exception {
+        ValueRange range = ValueRange.of(1, 2, 3, 4);
+        assertSerializable(range);
+    }
+
+
+    /**
+     * Verify Serialized bytes of a ValueRange.
+     * @throws IOException if thrown during serialization is an unexpected test tailure
+     */
+    public void test_valueRangeSerialized() throws IOException {
+        byte[] expected = {
+            (byte)172, (byte)237,   0,   5, 115, 114,   0,  29, 106,  97, /* \u00ac \u00ed \u0000 \u0005 s r \u0000 \u001d j a */
+            118,  97,  46, 116, 105, 109, 101,  46, 116, 101, /* v a . t i m e . t e */
+            109, 112, 111, 114,  97, 108,  46,  86,  97, 108, /* m p o r a l . V a l */
+            117, 101,  82,  97, 110, 103, 101, (byte)154, 113, (byte)169, /* u e R a n g e \u009a q \u00a9 */
+             86, (byte)242, (byte)205,  90, (byte)184,   2,   0,   4,  74,   0, /* V \u00f2 \u00cd Z \u00b8 \u0002 \u0000 \u0004 J \u0000 */
+             10, 109,  97, 120,  76,  97, 114, 103, 101, 115, /*  m a x L a r g e s */
+            116,  74,   0,  11, 109,  97, 120,  83, 109,  97, /* t J \u0000 \u000b m a x S m a */
+            108, 108, 101, 115, 116,  74,   0,  10, 109, 105,/* l l e s t J \u0000 m i */
+            110,  76,  97, 114, 103, 101, 115, 116,  74,   0, /* n L a r g e s t J \u0000 */
+             11, 109, 105, 110,  83, 109,  97, 108, 108, 101, /* \u000b m i n S m a l l e */
+            115, 116, 120, 112,   0,   0,   0,   0,   0,   0, /* s t x p \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 */
+              0,  40,   0,   0,   0,   0,   0,   0,   0,  30, /* \u0000 ( \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u001e */
+              0,   0,   0,   0,   0,   0,   0,  20,   0,   0, /* \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0014 \u0000 \u0000 */
+              0,   0,   0,   0,   0,  10,                     /* \u0000 \u0000 \u0000 \u0000 \u0000 */
+        };
+
+        ValueRange range = ValueRange.of(10, 20, 30, 40);
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos) ) {
+            oos.writeObject(range);
+
+            byte[] actual = baos.toByteArray();
+            assertEquals(actual, expected, "Serialized bytes incorrect");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/temporal/serial/TCKWeekFieldsSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2008-2012, 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.temporal.serial;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.io.IOException;
+import java.time.DayOfWeek;
+import java.time.temporal.WeekFields;
+
+/**
+ * Test serialization of WeekFields.
+ */
+@Test
+public class TCKWeekFieldsSerialization extends AbstractTCKTest {
+
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="weekFields")
+    public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException {
+        WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays);
+        assertSerializableSame(weekDef);  // spec state singleton
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="weekFields")
+    Object[][] data_weekFields() {
+        Object[][] objects = new Object[49][];
+        int i = 0;
+        for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) {
+            for (int minDays = 1; minDays <= 7; minDays++) {
+                objects[i++] = new Object[] {firstDayOfWeek, minDays};
+            }
+        }
+        return objects;
+    }
+
+
+}
--- a/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/zone/TCKFixedZoneRules.java	Tue Oct 08 14:57:32 2013 -0700
@@ -107,25 +107,7 @@
     //-----------------------------------------------------------------------
     // Basics
     //-----------------------------------------------------------------------
-    @Test(dataProvider="rules")
-    public void test_serialization(ZoneRules test, ZoneOffset expectedOffset) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(test);
-        baos.close();
-        byte[] bytes = baos.toByteArray();
 
-        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-        ObjectInputStream in = new ObjectInputStream(bais);
-        ZoneRules result = (ZoneRules) in.readObject();
-
-        assertEquals(result, test);
-        assertEquals(result.getClass(), test.getClass());
-    }
-
-    //-----------------------------------------------------------------------
-    // basics
-    //-----------------------------------------------------------------------
     @Test(dataProvider="rules")
     public void test_getOffset_Instant(ZoneRules test, ZoneOffset expectedOffset) {
         assertEquals(test.getOffset(INSTANT), expectedOffset);
--- a/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/zone/TCKZoneOffsetTransition.java	Tue Oct 08 14:57:32 2013 -0700
@@ -127,7 +127,6 @@
         assertEquals(test.getOffsetBefore(), OFFSET_0200);
         assertEquals(test.getOffsetAfter(), OFFSET_0300);
         assertEquals(test.getDuration(), Duration.of(1, HOURS));
-        assertSerializable(test);
     }
 
     @Test
@@ -143,23 +142,8 @@
         assertEquals(test.getOffsetBefore(), OFFSET_0300);
         assertEquals(test.getOffsetAfter(), OFFSET_0200);
         assertEquals(test.getDuration(), Duration.of(-1, HOURS));
-        assertSerializable(test);
     }
 
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_serialization_unusual1() throws Exception {
-        LocalDateTime ldt = LocalDateTime.of(Year.MAX_VALUE, 12, 31, 1, 31, 53);
-        ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("-10:02:34"));
-        assertSerializable(test);
-    }
-
-    @Test
-    public void test_serialization_unusual2() throws Exception {
-        LocalDateTime ldt = LocalDateTime.of(Year.MIN_VALUE, 1, 1, 12, 1, 3);
-        ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("+10:02:34"));
-        assertSerializable(test);
-    }
 
     //-----------------------------------------------------------------------
     // isValidOffset()
--- a/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/zone/TCKZoneOffsetTransitionRule.java	Tue Oct 08 14:57:32 2013 -0700
@@ -173,7 +173,6 @@
         assertEquals(test.getStandardOffset(), OFFSET_0200);
         assertEquals(test.getOffsetBefore(), OFFSET_0200);
         assertEquals(test.getOffsetAfter(), OFFSET_0300);
-        assertSerializable(test);
     }
 
     @Test
@@ -190,7 +189,6 @@
         assertEquals(test.getStandardOffset(), OFFSET_0200);
         assertEquals(test.getOffsetBefore(), OFFSET_0200);
         assertEquals(test.getOffsetAfter(), OFFSET_0300);
-        assertSerializable(test);
     }
 
     @Test
@@ -207,34 +205,8 @@
         assertEquals(test.getStandardOffset(), OFFSET_0200);
         assertEquals(test.getOffsetBefore(), OFFSET_0200);
         assertEquals(test.getOffsetAfter(), OFFSET_0300);
-        assertSerializable(test);
-    }
-
-    @Test
-    public void test_serialization_unusualOffsets() throws Exception {
-        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
-                Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD,
-                ZoneOffset.ofHoursMinutesSeconds(-12, -20, -50),
-                ZoneOffset.ofHoursMinutesSeconds(-4, -10, -34),
-                ZoneOffset.ofHours(-18));
-        assertSerializable(test);
     }
 
-    @Test
-    public void test_serialization_endOfDay() throws Exception {
-        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
-                Month.MARCH, 20, DayOfWeek.FRIDAY, LocalTime.MIDNIGHT, true, TimeDefinition.UTC,
-                OFFSET_0200, OFFSET_0200, OFFSET_0300);
-        assertSerializable(test);
-    }
-
-    @Test
-    public void test_serialization_unusualTime() throws Exception {
-        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
-                Month.MARCH, 20, DayOfWeek.WEDNESDAY, LocalTime.of(13, 34, 56), false, TimeDefinition.STANDARD,
-                OFFSET_0200, OFFSET_0200, OFFSET_0300);
-        assertSerializable(test);
-    }
 
     //-----------------------------------------------------------------------
     // createTransition()
--- a/test/java/time/tck/java/time/zone/TCKZoneRules.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/tck/java/time/zone/TCKZoneRules.java	Tue Oct 08 14:57:32 2013 -0700
@@ -103,28 +103,7 @@
     private static final int OVERLAP = 2;
     private static final int GAP = 0;
 
-    //-----------------------------------------------------------------------
-    // Basics
-    //-----------------------------------------------------------------------
-    public void test_serialization_loaded() throws Exception {
-        assertSerialization(europeLondon());
-        assertSerialization(europeParis());
-        assertSerialization(americaNewYork());
-    }
 
-    private void assertSerialization(ZoneRules test) throws Exception {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(test);
-        baos.close();
-        byte[] bytes = baos.toByteArray();
-
-        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-        ObjectInputStream in = new ObjectInputStream(bais);
-        ZoneRules result = (ZoneRules) in.readObject();
-
-        assertEquals(result, test);
-    }
 
     //-----------------------------------------------------------------------
     // Europe/London
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/zone/serial/TCKFixedZoneRulesSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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-2012, 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.zone.serial;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.ZoneOffset;
+import java.time.zone.ZoneRules;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test serialization of ZoneRules for fixed offset time-zones.
+ */
+@Test
+public class TCKFixedZoneRulesSerialization {
+
+    private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
+    private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
+    private static final ZoneOffset OFFSET_M18 = ZoneOffset.ofHours(-18);
+
+    private ZoneRules make(ZoneOffset offset) {
+        return offset.getRules();
+    }
+
+    @DataProvider(name="rules")
+    Object[][] data_rules() {
+        return new Object[][] {
+            {make(OFFSET_PONE), OFFSET_PONE},
+            {make(OFFSET_PTWO), OFFSET_PTWO},
+            {make(OFFSET_M18), OFFSET_M18},
+        };
+    }
+
+    //-----------------------------------------------------------------------
+    // Basics
+    //-----------------------------------------------------------------------
+    @Test(dataProvider="rules")
+    public void test_serialization(ZoneRules test, ZoneOffset expectedOffset) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+        out.writeObject(test);
+        baos.close();
+        byte[] bytes = baos.toByteArray();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream in = new ObjectInputStream(bais);
+        ZoneRules result = (ZoneRules) in.readObject();
+
+        assertEquals(result, test);
+        assertEquals(result.getClass(), test.getClass());
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionRuleSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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-2012, 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.zone.serial;
+
+import java.time.DayOfWeek;
+import java.time.LocalTime;
+import java.time.Month;
+import java.time.ZoneOffset;
+import java.time.zone.ZoneOffsetTransitionRule;
+import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition;
+
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+/**
+ * Test ZoneOffsetTransitionRule serialization.
+ */
+@Test
+public class TCKZoneOffsetTransitionRuleSerialization extends AbstractTCKTest {
+
+    private static final LocalTime TIME_0100 = LocalTime.of(1, 0);
+    private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2);
+    private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3);
+
+
+    //-----------------------------------------------------------------------
+    // Test serialization
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization_unusualOffsets() throws Exception {
+        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
+                Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.STANDARD,
+                ZoneOffset.ofHoursMinutesSeconds(-12, -20, -50),
+                ZoneOffset.ofHoursMinutesSeconds(-4, -10, -34),
+                ZoneOffset.ofHours(-18));
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_endOfDay() throws Exception {
+        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
+                Month.MARCH, 20, DayOfWeek.FRIDAY, LocalTime.MIDNIGHT, true, TimeDefinition.UTC,
+                OFFSET_0200, OFFSET_0200, OFFSET_0300);
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_unusualTime() throws Exception {
+        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
+                Month.MARCH, 20, DayOfWeek.WEDNESDAY, LocalTime.of(13, 34, 56), false, TimeDefinition.STANDARD,
+                OFFSET_0200, OFFSET_0200, OFFSET_0300);
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_floatingWeek() throws Exception {
+        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
+                Month.MARCH, 20, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
+                OFFSET_0200, OFFSET_0200, OFFSET_0300);
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_floatingWeekBackwards() throws Exception {
+        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
+                Month.MARCH, -1, DayOfWeek.SUNDAY, TIME_0100, false, TimeDefinition.WALL,
+                OFFSET_0200, OFFSET_0200, OFFSET_0300);
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_fixedDate() throws Exception {
+        ZoneOffsetTransitionRule test = ZoneOffsetTransitionRule.of(
+                Month.MARCH, 20, null, TIME_0100, false, TimeDefinition.WALL,
+                OFFSET_0200, OFFSET_0200, OFFSET_0300);
+        assertSerializable(test);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/zone/serial/TCKZoneOffsetTransitionSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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.
+ */
+
+/*
+ * 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-2012, 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.zone.serial;
+
+import static java.time.temporal.ChronoUnit.HOURS;
+
+import java.time.Duration;
+import org.testng.annotations.Test;
+import tck.java.time.AbstractTCKTest;
+
+import java.time.LocalDateTime;
+import java.time.Year;
+import java.time.ZoneOffset;
+import java.time.zone.ZoneOffsetTransition;
+
+/**
+ * Test serialization of ZoneOffsetTransition.
+ */
+@Test
+public class TCKZoneOffsetTransitionSerialization extends AbstractTCKTest {
+
+    private static final ZoneOffset OFFSET_0200 = ZoneOffset.ofHours(2);
+    private static final ZoneOffset OFFSET_0300 = ZoneOffset.ofHours(3);
+
+    //-----------------------------------------------------------------------
+    @Test
+    public void test_serialization_unusual1() throws Exception {
+        LocalDateTime ldt = LocalDateTime.of(Year.MAX_VALUE, 12, 31, 1, 31, 53);
+        ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("-10:02:34"));
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_unusual2() throws Exception {
+        LocalDateTime ldt = LocalDateTime.of(Year.MIN_VALUE, 1, 1, 12, 1, 3);
+        ZoneOffsetTransition test = ZoneOffsetTransition.of(ldt, ZoneOffset.of("+02:04:56"), ZoneOffset.of("+10:02:34"));
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_gap() throws Exception {
+        LocalDateTime before = LocalDateTime.of(2010, 3, 31, 1, 0);
+        LocalDateTime after = LocalDateTime.of(2010, 3, 31, 2, 0);
+        ZoneOffsetTransition test = ZoneOffsetTransition.of(before, OFFSET_0200, OFFSET_0300);
+        assertSerializable(test);
+    }
+
+    @Test
+    public void test_serialization_overlap() throws Exception {
+        LocalDateTime before = LocalDateTime.of(2010, 10, 31, 1, 0);
+        LocalDateTime after = LocalDateTime.of(2010, 10, 31, 0, 0);
+        ZoneOffsetTransition test = ZoneOffsetTransition.of(before, OFFSET_0300, OFFSET_0200);
+        assertSerializable(test);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/tck/java/time/zone/serial/TCKZoneRulesSerialization.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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) 2008-2012, 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.zone.serial;
+
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.ZoneId;
+import java.time.zone.ZoneRules;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test serialization of ZoneRules.
+ */
+@Test
+public class TCKZoneRulesSerialization {
+
+    public void test_serialization_loaded() throws Exception {
+        assertSerialization(europeLondon());
+        assertSerialization(europeParis());
+        assertSerialization(americaNewYork());
+    }
+
+    private void assertSerialization(ZoneRules test) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+        out.writeObject(test);
+        baos.close();
+        byte[] bytes = baos.toByteArray();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ObjectInputStream in = new ObjectInputStream(bais);
+        ZoneRules result = (ZoneRules) in.readObject();
+
+        assertEquals(result, test);
+    }
+
+    //-----------------------------------------------------------------------
+    // Europe/London
+    //-----------------------------------------------------------------------
+    private ZoneRules europeLondon() {
+        return ZoneId.of("Europe/London").getRules();
+    }
+
+
+    //-----------------------------------------------------------------------
+    // Europe/Paris
+    //-----------------------------------------------------------------------
+    private ZoneRules europeParis() {
+        return ZoneId.of("Europe/Paris").getRules();
+    }
+
+    //-----------------------------------------------------------------------
+    // America/New_York
+    //-----------------------------------------------------------------------
+    private ZoneRules americaNewYork() {
+        return ZoneId.of("America/New_York").getRules();
+    }
+
+
+}
--- a/test/java/time/test/java/time/AbstractTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/test/java/time/AbstractTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -63,11 +63,6 @@
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
@@ -87,27 +82,6 @@
         return true;
     }
 
-    protected static void assertSerializable(Object o) throws IOException, ClassNotFoundException {
-        Object deserialisedObject = writeThenRead(o);
-        assertEquals(deserialisedObject, o);
-    }
-
-    protected static void assertSerializableAndSame(Object o) throws IOException, ClassNotFoundException {
-        Object deserialisedObject = writeThenRead(o);
-        assertSame(deserialisedObject, o);
-    }
-
-    private static Object writeThenRead(Object o) throws IOException, ClassNotFoundException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) {
-            oos.writeObject(o);
-        }
-
-        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
-            return ois.readObject();
-        }
-    }
-
     protected static void assertImmutable(Class<?> cls) {
         assertTrue(Modifier.isPublic(cls.getModifiers()));
         assertTrue(Modifier.isFinal(cls.getModifiers()));
--- a/test/java/time/test/java/time/TestDuration.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/test/java/time/TestDuration.java	Tue Oct 08 14:57:32 2013 -0700
@@ -63,11 +63,6 @@
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
 import java.time.Duration;
 
 import org.testng.annotations.Test;
@@ -84,29 +79,6 @@
         assertImmutable(Duration.class);
     }
 
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_interfaces() {
-        assertTrue(Serializable.class.isAssignableFrom(Duration.class));
-        assertTrue(Comparable.class.isAssignableFrom(Duration.class));
-    }
-
-    //-----------------------------------------------------------------------
-    // serialization
-    //-----------------------------------------------------------------------
-    @Test
-    public void test_deserializationSingleton() throws Exception {
-        Duration orginal = Duration.ZERO;
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream out = new ObjectOutputStream(baos);
-        out.writeObject(orginal);
-        out.close();
-        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-        ObjectInputStream in = new ObjectInputStream(bais);
-        Duration ser = (Duration) in.readObject();
-        assertSame(ser, Duration.ZERO);
-    }
-
     @Test
     public void plus_zeroReturnsThis() {
         Duration t = Duration.ofSeconds(-1);
--- a/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java	Tue Oct 08 14:57:32 2013 -0700
@@ -26,9 +26,9 @@
 package test.java.time.chrono;
 
 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.DAY_OF_YEAR;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
@@ -39,12 +39,12 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.OffsetDateTime;
-import java.time.Period;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.time.chrono.ChronoLocalDate;
 import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoPeriod;
 import java.time.chrono.ChronoZonedDateTime;
 import java.time.chrono.Chronology;
 import java.time.chrono.HijrahChronology;
@@ -330,26 +330,26 @@
     @DataProvider(name="datesForPeriod")
     Object[][] data_Period() {
         return new Object[][] {
-            {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), Period.of(84, 2, 5)},
-            {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), Period.of(31, 1, 22)},
-            {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), Period.of(49, 6, 24)},
-            {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), Period.of(-50, -1, -20)},
-            {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), Period.of(0, 11, 28)},
+            {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(84, 2, 5)},
+            {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(31, 1, 22)},
+            {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), HijrahChronology.INSTANCE.period(49, 6, 24)},
+            {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), HijrahChronology.INSTANCE.period(-50, -1, -20)},
+            {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), HijrahChronology.INSTANCE.period(0, 11, 28)},
         };
     }
 
     // Test to get the Period between two given dates
     @Test(dataProvider="datesForPeriod")
-    public void test_until(HijrahDate h1, HijrahDate h2, Period p) {
-        Period period = h1.until(h2);
+    public void test_until(HijrahDate h1, HijrahDate h2, ChronoPeriod p) {
+        ChronoPeriod period = h1.until(h2);
         assertEquals(period, p);
     }
 
     // Test to get the Period between dates in different chronologies
     @Test(dataProvider="datesForPeriod")
-    public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, Period p) {
+    public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, ChronoPeriod p) {
         MinguoDate m = MinguoChronology.INSTANCE.date(h2);
-        Period period = h1.until(m);
+        ChronoPeriod period = h1.until(m);
         assertEquals(period, p);
     }
 
--- a/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/time/test/java/time/temporal/TestDateTimeValueRange.java	Tue Oct 08 14:57:32 2013 -0700
@@ -88,19 +88,6 @@
     }
 
     //-----------------------------------------------------------------------
-    // Serialization
-    //-----------------------------------------------------------------------
-    public void test_serialization() throws Exception {
-        Object obj = ValueRange.of(1, 2, 3, 4);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-        oos.writeObject(obj);
-        oos.close();
-        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
-        assertEquals(ois.readObject(), obj);
-    }
-
-    //-----------------------------------------------------------------------
     // of(long,long)
     //-----------------------------------------------------------------------
     public void test_of_longlong() {
--- a/test/java/util/Arrays/ParallelPrefix.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/Arrays/ParallelPrefix.java	Tue Oct 08 14:57:32 2013 -0700
@@ -22,7 +22,7 @@
  */
 
 /**
- * @test
+ * @test 8014076 8025067
  * @summary unit test for Arrays.ParallelPrefix().
  * @author Tristan Yan
  * @run testng ParallelPrefix
@@ -54,30 +54,44 @@
     private final static int LARGE_ARRAY_SIZE = 1 << 12;
 
     private final static int[] ARRAY_SIZE_COLLECTION  = new int[]{
-        SMALL_ARRAY_SIZE, THRESHOLD_ARRAY_SIZE,MEDIUM_ARRAY_SIZE, LARGE_ARRAY_SIZE};
+        SMALL_ARRAY_SIZE,
+        THRESHOLD_ARRAY_SIZE,
+        MEDIUM_ARRAY_SIZE,
+        LARGE_ARRAY_SIZE
+    };
 
     @DataProvider
     public static Object[][] intSet(){
-        return genericData(size -> IntStream.range(0, size).toArray(), new IntBinaryOperator[]{Integer::sum, Integer::min});
+        return genericData(size -> IntStream.range(0, size).toArray(),
+                new IntBinaryOperator[]{
+                    Integer::sum,
+                    Integer::min});
     }
 
     @DataProvider
     public static Object[][] longSet(){
-        return genericData(size -> LongStream.range(0, size).toArray(), new LongBinaryOperator[]{Long::sum, Long::min});
+        return genericData(size -> LongStream.range(0, size).toArray(),
+                new LongBinaryOperator[]{
+                    Long::sum,
+                    Long::min});
     }
 
     @DataProvider
     public static Object[][] doubleSet(){
         return genericData(size -> IntStream.range(0, size).mapToDouble(i -> (double)i).toArray(),
-                new DoubleBinaryOperator[]{Double::sum, Double::min});
+                new DoubleBinaryOperator[]{
+                    Double::sum,
+                    Double::min});
     }
 
     @DataProvider
     public static Object[][] stringSet(){
         Function<Integer, String[]> stringsFunc = size ->
                 IntStream.range(0, size).mapToObj(Integer::toString).toArray(String[]::new);
-        BinaryOperator<String> cancatBop = String::concat;
-        return genericData(stringsFunc,  new BinaryOperator[]{cancatBop});
+        BinaryOperator<String> concat = String::concat;
+        return genericData(stringsFunc,
+                (BinaryOperator<String>[]) new BinaryOperator[]{
+                    concat });
     }
 
     private static <T, OPS> Object[][] genericData(Function<Integer, T> generateFunc, OPS[] ops) {
@@ -161,5 +175,123 @@
         Arrays.parallelPrefix(parallelRangeResult, op);
         assertEquals(parallelRangeResult, Arrays.copyOfRange(sequentialResult, fromIndex, toIndex));
     }
+
+    @Test
+    public void testNPEs() {
+        // null array
+        assertThrows( () -> Arrays.parallelPrefix((int[]) null, Integer::max),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix((long []) null, Long::max),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix((double []) null, Double::max),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix((String []) null, String::concat),
+                NullPointerException.class, "should throw NPE");
+
+        // null array w/ range
+        assertThrows( () -> Arrays.parallelPrefix((int[]) null, 0, 0, Integer::max),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix((long []) null, 0, 0, Long::max),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix((double []) null, 0, 0, Double::max),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix((String []) null, 0, 0, String::concat),
+                NullPointerException.class, "should throw NPE");
+
+        // null op
+        assertThrows( () -> Arrays.parallelPrefix(new int[] {}, null),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix(new long[] {}, null),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix(new double[] {}, null),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix(new String[] {}, null),
+                NullPointerException.class, "should throw NPE");
+
+        // null op w/ range
+        assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 0, null),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 0, null),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 0, null),
+                NullPointerException.class, "should throw NPE");
+        assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 0, null),
+                NullPointerException.class, "should throw NPE");
+    }
+
+    @Test
+    public void testIAEs() {
+        assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 1, 0, Integer::max),
+                IllegalArgumentException.class, "should throw IAE");
+        assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 1, 0, Long::max),
+                IllegalArgumentException.class, "should throw IAE");
+        assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 1, 0, Double::max),
+                IllegalArgumentException.class, "should throw IAE");
+        assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 1, 0, String::concat),
+                IllegalArgumentException.class, "should throw IAE");
+    }
+
+    @Test
+    public void testAIOBEs() {
+        // bad "fromIndex"
+        assertThrows( () -> Arrays.parallelPrefix(new int[] {}, -1, 0, Integer::max),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+        assertThrows( () -> Arrays.parallelPrefix(new long[] {}, -1, 0, Long::max),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+        assertThrows( () -> Arrays.parallelPrefix(new double[] {}, -1, 0, Double::max),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+        assertThrows( () -> Arrays.parallelPrefix(new String[] {}, -1, 0, String::concat),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+
+        // bad "toIndex"
+        assertThrows( () -> Arrays.parallelPrefix(new int[] {}, 0, 1, Integer::max),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+        assertThrows( () -> Arrays.parallelPrefix(new long[] {}, 0, 1, Long::max),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+        assertThrows( () -> Arrays.parallelPrefix(new double[] {}, 0, 1, Double::max),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+        assertThrows( () -> Arrays.parallelPrefix(new String[] {}, 0, 1, String::concat),
+                ArrayIndexOutOfBoundsException.class, "should throw AIOBE");
+    }
+
+    // "library" code
+
+    public interface Thrower<T extends Throwable> {
+
+        public void run() throws T;
+    }
+
+
+    public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable) {
+        assertThrows(thrower, throwable, null);
+    }
+
+    public static <T extends Throwable> void assertThrows(Thrower<T> thrower, Class<T> throwable, String message) {
+        Throwable thrown;
+        try {
+            thrower.run();
+            thrown = null;
+        } catch (Throwable caught) {
+            thrown = caught;
+        }
+
+        assertInstance(thrown, throwable,
+            ((null != message) ? message : "") +
+            " Failed to throw " + throwable.getCanonicalName());
+    }
+
+    public static <T extends Throwable> void assertThrows(Class<T> throwable, String message, Thrower<T>... throwers) {
+        for(Thrower<T> thrower : throwers) {
+            assertThrows(thrower, throwable, message);
+        }
+    }
+
+    public static void assertInstance(Object actual, Class<?> expected) {
+        assertInstance(expected.isInstance(actual), null);
+    }
+
+    public static void assertInstance(Object actual, Class<?> expected, String message) {
+        assertTrue(expected.isInstance(actual), message);
+    }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Calendar/Bug6902861.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,69 @@
+/*
+ * 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 6902861
+ * @summary Test for a workaround when WEEK_OF_YEAR and YEAR are out of sync.
+ */
+
+import java.util.*;
+import static java.util.GregorianCalendar.*;
+
+public class Bug6902861 {
+    static int errors = 0;
+
+    public static void main(String [] args) {
+        Locale loc = Locale.getDefault();
+        try {
+            Locale.setDefault(Locale.GERMANY);
+            test(2010, JANUARY, 1, +1, 1);
+            test(2010, JANUARY, 1, +2, 2);
+            test(2010, JANUARY, 1, -1, 52);
+            test(2010, JANUARY, 1, -2, 51);
+            test(2008, DECEMBER, 31, +1, 1);
+            test(2008, DECEMBER, 31, +2, 2);
+            test(2008, DECEMBER, 31, -1, 52);
+            test(2008, DECEMBER, 31, -2, 51);
+            if (errors > 0) {
+                throw new RuntimeException("Failed");
+            }
+        } finally {
+            Locale.setDefault(loc);
+        }
+    }
+
+    static void test(int year, int month, int dayOfMonth, int amount, int expected) {
+        Calendar calendar = new GregorianCalendar(year, month, dayOfMonth);
+        int week = calendar.get(WEEK_OF_YEAR); // fix the date
+        calendar.roll(WEEK_OF_YEAR, amount);
+        int got = calendar.get(WEEK_OF_YEAR);
+        int y = calendar.get(YEAR);
+        if (got != expected || y != year) {
+            String date = String.format("%04d-%02d-%02d", year, month+1, dayOfMonth);
+            System.err.printf("%s: roll %+d: got: %d,%2d; expected: %d,%2d%n",
+                              date, amount, y, got, year, expected);
+            errors++;
+        }
+    }
+}
--- a/test/java/util/Collection/MOAT.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/Collection/MOAT.java	Tue Oct 08 14:57:32 2013 -0700
@@ -207,8 +207,8 @@
                new Fun(){void f(){ it.next(); }});
 
         try { it.remove(); }
-        catch (IllegalStateException _) { pass(); }
-        catch (UnsupportedOperationException _) { pass(); }
+        catch (IllegalStateException ignored) { pass(); }
+        catch (UnsupportedOperationException ignored) { pass(); }
         catch (Throwable t) { unexpected(t); }
 
         if (rnd.nextBoolean())
@@ -280,9 +280,9 @@
         testEmptyCollection(m.values());
 
         try { check(! m.containsValue(null)); }
-        catch (NullPointerException _) { /* OK */ }
+        catch (NullPointerException ignored) { /* OK */ }
         try { check(! m.containsKey(null)); }
-        catch (NullPointerException _) { /* OK */ }
+        catch (NullPointerException ignored) { /* OK */ }
         check(! m.containsValue(1));
         check(! m.containsKey(1));
     }
@@ -710,8 +710,8 @@
             l.addAll(-1, Collections.<Integer>emptyList());
             fail("Expected IndexOutOfBoundsException not thrown");
         }
-        catch (UnsupportedOperationException _) {/* OK */}
-        catch (IndexOutOfBoundsException _) {/* OK */}
+        catch (UnsupportedOperationException ignored) {/* OK */}
+        catch (IndexOutOfBoundsException ignored) {/* OK */}
         catch (Throwable t) { unexpected(t); }
 
 //      equal(l instanceof Serializable,
--- a/test/java/util/Spliterator/SpliteratorCharacteristics.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/Spliterator/SpliteratorCharacteristics.java	Tue Oct 08 14:57:32 2013 -0700
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8020156 8020009 8022326 8012913 8024405
+ * @bug 8020156 8020009 8022326 8012913 8024405 8024408
  * @run testng SpliteratorCharacteristics
  */
 
@@ -46,6 +46,7 @@
 import java.util.Spliterators;
 import java.util.TreeMap;
 import java.util.TreeSet;
+import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.ConcurrentSkipListSet;
 import java.util.function.Supplier;
@@ -185,6 +186,11 @@
                                  Spliterator.SIZED | Spliterator.DISTINCT);
     }
 
+    public void testWeakHashMap() {
+        assertMapCharacteristics(new WeakHashMap<>(),
+                                 Spliterator.DISTINCT);
+    }
+
     public void testHashSet() {
         assertSetCharacteristics(new HashSet<>(),
                                  Spliterator.SIZED | Spliterator.DISTINCT);
--- a/test/java/util/TreeMap/Clone.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/TreeMap/Clone.java	Tue Oct 08 14:57:32 2013 -0700
@@ -27,7 +27,6 @@
  * @summary Verify that cloned TreeMap gets new keyset
  * @author david.buck@oracle.com
  * @run main/othervm Clone
- * @run main/othervm -XX:+AggressiveOpts Clone
  */
 
 import java.util.TreeMap;
--- a/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java	Tue Oct 08 14:57:32 2013 -0700
@@ -30,7 +30,6 @@
 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;
@@ -41,7 +40,6 @@
 import java.util.function.Consumer;
 import java.util.function.Function;
 
-import org.testng.Assert;
 import org.testng.annotations.Test;
 
 /**
@@ -397,14 +395,68 @@
 
     // 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,
+    interface BaseTerminalTestScenario<U, R, S_OUT extends BaseStream<U, S_OUT>> {
+        boolean requiresSingleStageSource();
+
+        boolean requiresParallelSource();
+
+        default R run(Function<S_OUT, R> terminalF, S_OUT source, StreamShape shape) {
+            return terminalF.apply(source);
+        }
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    static enum TerminalTestScenario implements BaseTerminalTestScenario {
+        SINGLE_SEQUENTIAL(true, false),
+
+        SINGLE_SEQUENTIAL_SHORT_CIRCUIT(true, false) {
+            @Override
+            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
+                source = (BaseStream) chain(source, new ShortCircuitOp(shape));
+                return terminalF.apply(source);
+            }
+        },
+
+        SINGLE_PARALLEL(true, true),
+
+        ALL_SEQUENTIAL(false, false),
+
+        ALL_SEQUENTIAL_SHORT_CIRCUIT(false, false) {
+            @Override
+            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
+                source = (BaseStream) chain(source, new ShortCircuitOp(shape));
+                return terminalF.apply(source);
+            }
+        },
+
+        ALL_PARALLEL(false, true),
+
+        ALL_PARALLEL_SEQUENTIAL(false, false) {
+            @Override
+            public Object run(Function terminalF, BaseStream source, StreamShape shape) {
+                return terminalF.apply(source.sequential());
+            }
+        },
+        ;
+
+        private final boolean requiresSingleStageSource;
+        private final boolean isParallel;
+
+        TerminalTestScenario(boolean requiresSingleStageSource, boolean isParallel) {
+            this.requiresSingleStageSource = requiresSingleStageSource;
+            this.isParallel = isParallel;
+        }
+
+        @Override
+        public boolean requiresSingleStageSource() {
+            return requiresSingleStageSource;
+        }
+
+        @Override
+        public boolean requiresParallelSource() {
+            return isParallel;
+        }
+
     }
 
     @SuppressWarnings({"rawtypes", "unchecked"})
@@ -415,8 +467,6 @@
 
         R refResult;
 
-        Set<TerminalTestScenario> testSet = EnumSet.allOf(TerminalTestScenario.class);
-
         ResultAsserter<R> resultAsserter = (act, exp, ord, par) -> LambdaTestHelpers.assertContentsEqual(act, exp);
 
         private ExerciseDataTerminalBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
@@ -442,27 +492,6 @@
             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() {
@@ -471,70 +500,36 @@
             boolean isOrdered = StreamOpFlag.ORDERED.isKnown(ap.getStreamFlags());
             StreamShape shape = ap.getOutputShape();
 
+            EnumSet<TerminalTestScenario> tests = EnumSet.allOf(TerminalTestScenario.class);
+            // Sequentially collect the output that will be input to the terminal op
             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);
-                R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
-                                                   () -> String.format("Single sequential: %s != %s", refResult, result));
-            }
-
-            if (testSet.contains(TerminalTestScenario.SINGLE_SEQUENTIAL_SHORT_CIRCUIT)) {
+                // Induce the reference result
                 S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
                                                       StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
                                                       false);
-                // Force short-circuit
-                source = (S_OUT) chain(source, new ShortCircuitOp<U>(shape));
-                R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
-                                                   () -> 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);
-                R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, true),
-                                                   () -> String.format("Single parallel: %s != %s", refResult, result));
+                refResult = (R) TerminalTestScenario.SINGLE_SEQUENTIAL.run(terminalF, source, shape);
+                tests.remove(TerminalTestScenario.SINGLE_SEQUENTIAL);
             }
 
-            if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL)) {
-                // This may forEach or tryAdvance depending on the terminal op implementation
-                S_OUT source = streamF.apply(data.stream());
-                R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
-                                                   () -> String.format("All sequential: %s != %s", refResult, result));
-            }
+            for (BaseTerminalTestScenario test : tests) {
+                S_OUT source;
+                if (test.requiresSingleStageSource()) {
+                    source = (S_OUT) createPipeline(shape, node.spliterator(),
+                                                    StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
+                                                    test.requiresParallelSource());
+                }
+                else {
+                    source = streamF.apply(test.requiresParallelSource()
+                                           ? data.parallelStream() : data.stream());
+                }
 
-            if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL_SHORT_CIRCUIT)) {
-                S_OUT source = streamF.apply(data.stream());
-                // Force short-circuit
-                source = (S_OUT) chain(source, new ShortCircuitOp<U>(shape));
-                R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
-                                                   () -> String.format("All sequential pull: %s != %s", refResult, result));
-            }
+                R result = (R) test.run(terminalF, source, shape);
 
-            if (testSet.contains(TerminalTestScenario.ALL_PARALLEL)) {
-                S_OUT source = streamF.apply(data.parallelStream());
-                R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, true),
-                                                   () -> String.format("All parallel: %s != %s", refResult, result));
-            }
-
-            if (testSet.contains(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL)) {
-                S_OUT source = streamF.apply(data.parallelStream());
-                R result = terminalF.apply(source.sequential());
-                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
-                                                   () -> String.format("All parallel then sequential: %s != %s", refResult, result));
+                LambdaTestHelpers.launderAssertion(
+                        () -> resultAsserter.assertResult(result, refResult, isOrdered, test.requiresParallelSource()),
+                        () -> String.format("%s: %s != %s", test, refResult, result));
             }
 
             return refResult;
@@ -596,10 +591,10 @@
 
     // Test data
 
-    private class ShortCircuitOp<T> implements StatelessTestOp<T,T> {
+    static class ShortCircuitOp<T> implements StatelessTestOp<T,T> {
         private final StreamShape shape;
 
-        private ShortCircuitOp(StreamShape shape) {
+        ShortCircuitOp(StreamShape shape) {
             this.shape = shape;
         }
 
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ExplodeOpTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -64,6 +64,9 @@
         result = exerciseOps(data, s -> s.flatMap(mfNull));
         assertEquals(0, result.size());
 
+        result = exerciseOps(data, s-> s.flatMap(e -> Stream.empty()));
+        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)));
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -69,7 +69,7 @@
         };
     }
 
-    @Test
+    @Test(groups = { "serialization-hostile" })
     public void testForEachOrdered() {
         List<Integer> input = countTo(10000);
         TestData.OfRef<Integer> data = TestData.Factory.ofCollection("[1, 10000]", input);
@@ -116,7 +116,7 @@
 
     //
 
-    @Test
+    @Test(groups = { "serialization-hostile" })
     public void testIntForEachOrdered() {
         List<Integer> input = countTo(10000);
         TestData.OfInt data = TestData.Factory.ofIntSupplier("[1, 10000]",
@@ -164,7 +164,7 @@
 
     //
 
-    @Test
+    @Test(groups = { "serialization-hostile" })
     public void testLongForEachOrdered() {
         List<Integer> input = countTo(10000);
         TestData.OfLong data = TestData.Factory.ofLongSupplier("[1, 10000]",
@@ -212,7 +212,7 @@
 
     //
 
-    @Test
+    @Test(groups = { "serialization-hostile" })
     public void testDoubleForEachOrdered() {
         List<Integer> input = countTo(10000);
         TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("[1, 10000]",
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -147,7 +147,8 @@
         return Math.max(0, dataSize - skip);
     }
 
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
     public void testSkipOps(String name, TestData.OfRef<Integer> data) {
         List<Integer> skips = sizes(data.size());
 
@@ -169,7 +170,8 @@
         }
     }
 
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
     public void testSkipLimitOps(String name, TestData.OfRef<Integer> data) {
         List<Integer> skips = sizes(data.size());
         List<Integer> limits = skips;
@@ -242,7 +244,8 @@
         testSkipLimitOps("testSkipLimitOpsWithNonSplittingSpliterator", data);
     }
 
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
     public void testLimitOps(String name, TestData.OfRef<Integer> data) {
         List<Integer> limits = sizes(data.size());
 
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SortedOpTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -26,6 +26,8 @@
 
 import java.util.*;
 import java.util.Spliterators;
+import java.util.function.Function;
+import java.util.function.Supplier;
 import java.util.stream.*;
 
 import static java.util.stream.LambdaTestHelpers.*;
@@ -37,6 +39,69 @@
  */
 @Test
 public class SortedOpTest extends OpTestCase {
+
+    public void testRefStreamTooLarge() {
+        Function<LongStream, Stream<Long>> f = s ->
+                // Clear the SORTED flag
+                s.mapToObj(i -> i)
+                .sorted();
+
+        testStreamTooLarge(f, Stream::findFirst);
+    }
+
+    public void testIntStreamTooLarge() {
+        Function<LongStream, IntStream> f = s ->
+                // Clear the SORTED flag
+                s.mapToInt(i -> (int) i)
+                .sorted();
+
+        testStreamTooLarge(f, IntStream::findFirst);
+    }
+
+    public void testLongStreamTooLarge() {
+        Function<LongStream, LongStream> f = s ->
+                // Clear the SORTED flag
+                s.map(i -> i)
+                .sorted();
+
+        testStreamTooLarge(f, LongStream::findFirst);
+    }
+
+    public void testDoubleStreamTooLarge() {
+        Function<LongStream, DoubleStream> f = s ->
+                // Clear the SORTED flag
+                s.mapToDouble(i -> (double) i)
+                .sorted();
+
+        testStreamTooLarge(f, DoubleStream::findFirst);
+    }
+
+    <T, S extends BaseStream<T, S>> void testStreamTooLarge(Function<LongStream, S> s,
+                                                            Function<S, ?> terminal) {
+        // Set up conditions for a large input > maximum array size
+        Supplier<LongStream> input = () -> LongStream.range(0, 1L + Integer.MAX_VALUE);
+
+        // Transformation functions
+        List<Function<LongStream, LongStream>> transforms = Arrays.asList(
+                ls -> ls,
+                ls -> ls.parallel(),
+                // Clear the SIZED flag
+                ls -> ls.limit(Long.MAX_VALUE),
+                ls -> ls.limit(Long.MAX_VALUE).parallel());
+
+        for (Function<LongStream, LongStream> transform : transforms) {
+            RuntimeException caught = null;
+            try {
+                terminal.apply(s.apply(transform.apply(input.get())));
+            } catch (RuntimeException e) {
+                caught = e;
+            }
+            assertNotNull(caught, "Expected an instance of exception IllegalArgumentException but no exception thrown");
+            assertTrue(caught instanceof IllegalArgumentException,
+                       String.format("Expected an instance of exception IllegalArgumentException but got %s", caught));
+        }
+    }
+
     public void testSorted() {
         assertCountSum(countTo(0).stream().sorted(), 0, 0);
         assertCountSum(countTo(10).stream().sorted(), 10, 55);
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -97,7 +97,7 @@
         checkISE(() -> sb.build());
     }
 
-    @Test(dataProvider = "sizes")
+    @Test(dataProvider = "sizes", groups = { "serialization-hostile" })
     public void testStreamBuilder(int size) {
         testStreamBuilder(size, (s) -> {
             Stream.Builder<Integer> sb = Stream.builder();
@@ -159,7 +159,7 @@
         checkISE(() -> sb.build());
     }
 
-    @Test(dataProvider = "sizes")
+    @Test(dataProvider = "sizes", groups = { "serialization-hostile" })
     public void testIntStreamBuilder(int size) {
         testIntStreamBuilder(size, (s) -> {
             IntStream.Builder sb = IntStream.builder();
@@ -221,7 +221,7 @@
         checkISE(() -> sb.build());
     }
 
-    @Test(dataProvider = "sizes")
+    @Test(dataProvider = "sizes", groups = { "serialization-hostile" })
     public void testLongStreamBuilder(int size) {
         testLongStreamBuilder(size, (s) -> {
             LongStream.Builder sb = LongStream.builder();
@@ -282,7 +282,7 @@
         checkISE(() -> sb.build());
     }
 
-    @Test(dataProvider = "sizes")
+    @Test(dataProvider = "sizes", groups = { "serialization-hostile" })
     public void testDoubleStreamBuilder(int size) {
         testDoubleStreamBuilder(size, (s) -> {
             DoubleStream.Builder sb = DoubleStream.builder();
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -609,7 +609,7 @@
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
         List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
-        List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::<Integer>unmodifiableList)));
+        List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList)));
         assertEquals(asList, asImmutableList);
         try {
             asImmutableList.add(0);
--- a/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -165,7 +165,8 @@
         };
     }
 
-    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
+    @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
+          groups = { "serialization-hostile" })
     public void testStatefulOpPermutations(String name, TestData.OfRef<Integer> data) {
         for (Function<Stream<Integer>, Stream<Integer>> f : statefulOpPermutations) {
             withData(data).terminal(f, s -> s.toArray())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8024707/TestFunc.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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 org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * bug 8024707
+ */
+
+public class TestFunc {
+        public static Node test( NodeList list ) {
+            return list.item(0);
+        }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8024707/XSLT.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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 8024707
+ * @summary Test for XSLT extension function with 1 element sized nodelist
+ * @compile TestFunc.java XSLT.java
+ * @run main/othervm XSLT
+ * @author aleksej.efimov@oracle.com
+ */
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+import java.io.ByteArrayOutputStream;
+
+public class XSLT {
+    static final String XMLTOTRANSFORM = "/in.xml";
+    static final String XSLTRANSFORMER = "/test.xsl";
+    static final String EXPECTEDRESULT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>inp1_1";
+
+    public static void main(String[] args) throws Exception {
+        ByteArrayOutputStream resStream = new ByteArrayOutputStream();
+        TransformerFactory trf = TransformerFactory.newInstance();
+        Transformer tr = trf.newTransformer( new StreamSource(System.getProperty("test.src", ".")+XSLTRANSFORMER));
+        tr.transform( new StreamSource(System.getProperty("test.src", ".")+XMLTOTRANSFORM), new StreamResult(resStream));
+        System.out.println("Transformation completed. Result:"+resStream.toString());
+        if (!resStream.toString().equals(EXPECTEDRESULT))
+            throw new RuntimeException("Incorrect transformation result");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8024707/in.xml	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+<input1><seq-elem1>inp1_1</seq-elem1></input1>
+</root>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/jaxp/parsers/8024707/test.xsl	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:transform exclude-result-prefixes="cscdt_ufunc" version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:cscdt_ufunc="http://xml.apache.org/xalan/java">
+    <xsl:template match="/">
+        <xsl:value-of
+            select="cscdt_ufunc:TestFunc.test(/root/input1/seq-elem1)"
+        />
+    </xsl:template>
+</xsl:transform>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/ws/clientjar/TestService.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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 javax.jws.WebService;
+
+@WebService(serviceName ="TestService", targetNamespace = "http://test/jaxws/sample/")
+public class TestService {
+    public void foo() {
+        try {
+            bar();
+        } catch (Exception e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    private void bar() {
+        // nothing done
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/javax/xml/ws/clientjar/TestWsImport.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,151 @@
+/*
+ * 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 8016271
+ * @summary wsimport -clientjar does not create portable jar on windows due to hardcoded '\'
+ * @run main/othervm TestWsImport
+ */
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.Service;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import static java.nio.file.FileVisitResult.*;
+import java.util.Enumeration;
+import java.util.jar.JarFile;
+
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpServer;
+
+public class TestWsImport {
+
+    public static void main(String[] args) throws IOException {
+
+        String javaHome = System.getProperty("java.home");
+        if (javaHome.endsWith("jre")) {
+            javaHome = new File(javaHome).getParent();
+        }
+        String wsimport = javaHome + File.separator + "bin" + File.separator + "wsimport";
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            wsimport = wsimport.concat(".exe");
+        }
+
+        Endpoint endpoint = Endpoint.create(new TestService());
+        HttpServer httpServer = null;
+        try {
+            // Manually create HttpServer here using ephemeral address for port
+            // so as to not end up with attempt to bind to an in-use port
+            httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+            HttpContext httpContext = httpServer.createContext("/hello");
+            int port = httpServer.getAddress().getPort();
+            System.out.println("port = " + port);
+            httpServer.start();
+            endpoint.publish(httpContext);
+            String address = "http://localhost:" + port + "/hello";
+
+            Service service = Service.create(new URL(address + "?wsdl"),
+                new QName("http://test/jaxws/sample/",
+                "TestService"));
+
+            String[] wsargs = {
+                wsimport,
+                "-p",
+                "wstest",
+                "-J-Djavax.xml.accessExternalSchema=all",
+                address + "?wsdl",
+                "-clientjar",
+                "wsjar.jar"
+            };
+            ProcessBuilder pb = new ProcessBuilder(wsargs);
+            pb.redirectErrorStream(true);
+            Process p = pb.start();
+            BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
+            String s = r.readLine();
+            while (s != null) {
+                System.out.println(s.trim());
+                s = r.readLine();
+            }
+            p.waitFor();
+            p.destroy();
+
+            try (JarFile jarFile = new JarFile("wsjar.jar")) {
+                for (Enumeration em = jarFile.entries(); em.hasMoreElements();) {
+                    String fileName = em.nextElement().toString();
+                    if (fileName.contains("\\")) {
+                        throw new RuntimeException("\"\\\" character detected in jar file: " + fileName);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e.getMessage());
+        } finally {
+            endpoint.stop();
+            if (httpServer != null) {
+                httpServer.stop(0);
+            }
+            Path p = Paths.get("wsjar.jar");
+            Files.deleteIfExists(p);
+            p = Paths.get("wstest");
+            if (Files.exists(p)) {
+                try {
+                    Files.walkFileTree(p, new SimpleFileVisitor<Path>() {
+                        @Override
+                        public FileVisitResult visitFile(Path file,
+                            BasicFileAttributes attrs) throws IOException {
+
+                            Files.delete(file);
+                            return CONTINUE;
+                        }
+                        @Override
+                        public FileVisitResult postVisitDirectory(Path dir,
+                            IOException exc) throws IOException {
+
+                            if (exc == null) {
+                                Files.delete(dir);
+                                return CONTINUE;
+                            } else {
+                                throw exc;
+                            }
+                        }
+                    });
+                } catch (IOException ioe) {
+                    ioe.printStackTrace();
+                }
+            }
+        }
+    }
+}
--- a/test/jdk/lambda/vm/DefaultMethodsTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/jdk/lambda/vm/DefaultMethodsTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -387,37 +387,6 @@
     }
 
     /**
-     * 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 {}
      *
@@ -470,58 +439,6 @@
         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; } }
@@ -665,33 +582,6 @@
 
     /**
      * 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;
@@ -737,69 +627,6 @@
         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");
--- a/test/sun/management/jdp/JdpTest.sh	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/sun/management/jdp/JdpTest.sh	Tue Oct 08 14:57:32 2013 -0700
@@ -84,15 +84,29 @@
   ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} ${testappname}  >> ${_logname} 2>&1 &
  _last_pid=$!
 
-  npid=`_get_pid`
-  if [ "${npid}" = "" ]
-  then
-     echo "ERROR: Test app not started. Please check machine resources before filing a bug."
-     if [ "${_jtreg}" = "yes" ]
-     then
-       exit 255
-     fi
-  fi
+# wait until VM is actually starts. 
+# please note, if vm doesn't start for some reason
+# jtreg kills the test by timeout. Don't file a bug.
+  cnt=1 
+  while true
+  do
+    npid=`_get_pid`
+    if [ "${npid}" != "" ]
+    then
+      break
+    fi
+    if [ "${cnt}" = "10" ]
+    then
+      echo "ERROR: Test app not started. Please check machine resources before filing a bug."
+      if [ "${_jtreg}" = "yes" ]
+      then
+          exit 255
+      fi
+      break
+    fi
+    cnt=`expr $cnt + 1`
+    sleep 1
+  done
 }
 
 _get_pid(){
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/jgss/spnego/MechTokenMissing.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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 8024861
+ * @summary Incomplete token triggers GSS-API NullPointerException
+ */
+
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+
+public class MechTokenMissing {
+    public static void main(String[] args) throws Exception {
+        GSSCredential cred = null;
+        GSSContext ctx = GSSManager.getInstance().createContext(cred);
+
+        String var =
+            /*0000*/ "60 1C 06 06 2B 06 01 05 05 02 A0 12 30 10 A0 0E " +
+            /*0010*/ "30 0C 06 0A 2B 06 01 04 01 82 37 02 02 0A ";
+        byte[] token = new byte[var.length()/3];
+        for (int i=0; i<token.length; i++) {
+            token[i] = Integer.valueOf(var.substring(3*i,3*i+2), 16).byteValue();
+        }
+        try {
+            ctx.acceptSecContext(token, 0, token.length);
+        } catch (GSSException gsse) {
+            System.out.println("Expected exception: " + gsse);
+        }
+    }
+}
--- a/test/sun/security/krb5/auto/SSL.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/sun/security/krb5/auto/SSL.java	Tue Oct 08 14:57:32 2013 -0700
@@ -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
@@ -23,11 +23,12 @@
 
 /*
  * @test
- * @bug 6894643 6913636 8005523
+ * @bug 6894643 6913636 8005523 8025123
  * @summary Test JSSE Kerberos ciphersuite
 
  * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA
  * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA unbound
+ * @run main/othervm SSL TLS_KRB5_WITH_RC4_128_SHA unbound sni
  * @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_SHA
  * @run main/othervm SSL TLS_KRB5_WITH_3DES_EDE_CBC_MD5
  * @run main/othervm SSL TLS_KRB5_WITH_DES_CBC_SHA
@@ -44,6 +45,9 @@
 import javax.net.ssl.*;
 import java.security.Principal;
 import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Locale;
 import javax.security.auth.kerberos.ServicePermission;
 import sun.security.jgss.GSSUtil;
 import sun.security.krb5.PrincipalName;
@@ -56,6 +60,8 @@
     private static int loopCount = 0;
     private static volatile String server;
     private static volatile int port;
+    private static String sniHostname = null;
+    private static String sniMatcherPattern = null;
 
     private static String permChecks = "";
 
@@ -84,11 +90,11 @@
         System.setSecurityManager(new SSL());
 
         KDC kdc = KDC.create(OneKDC.REALM);
-        // Run this after KDC, so our own DNS service can be started
-        try {
-            server = InetAddress.getLocalHost().getHostName().toLowerCase();
-        } catch (java.net.UnknownHostException e) {
-            server = "localhost";
+        server = "host." + OneKDC.REALM.toLowerCase(Locale.US);
+
+        if (args.length > 2) {
+            sniHostname = "test." + server;
+            sniMatcherPattern = ".*";
         }
 
         kdc.addPrincipal(OneKDC.USER, OneKDC.PASS);
@@ -98,15 +104,21 @@
 
         // Add 3 versions of keys into keytab
         KeyTab ktab = KeyTab.create(OneKDC.KTAB);
+        String serviceName = null;
+        if (sniHostname != null) {
+            serviceName = "host/" + sniHostname;
+        } else {
+            serviceName = "host/" + server;
+        }
         PrincipalName service = new PrincipalName(
-                "host/" + server, PrincipalName.KRB_NT_SRV_HST);
+            serviceName, PrincipalName.KRB_NT_SRV_HST);
         ktab.addEntry(service, "pass1".toCharArray(), 1, true);
         ktab.addEntry(service, "pass2".toCharArray(), 2, true);
         ktab.addEntry(service, "pass3".toCharArray(), 3, true);
         ktab.save();
 
         // and use the middle one as the real key
-        kdc.addPrincipal("host/" + server, "pass2".toCharArray());
+        kdc.addPrincipal(serviceName, "pass2".toCharArray());
 
 
         // JAAS config entry name ssl
@@ -118,7 +130,7 @@
                 "    com.sun.security.auth.module.Krb5LoginModule required\n" +
                 (unbound ?
                     "    principal=*\n" :
-                    "    principal=\"host/" + server + "\"\n") +
+                    "    principal=\"" + serviceName + "\"\n") +
                 "    useKeyTab=true\n" +
                 "    keyTab=" + OneKDC.KTAB + "\n" +
                 "    isInitiator=false\n" +
@@ -153,7 +165,7 @@
         }
 
         c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
-        c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
+        c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
         c.doAs(new JsseClientAction(), null);
 
         // Add another version of key, make sure it can be loaded
@@ -161,10 +173,10 @@
         ktab = KeyTab.getInstance(OneKDC.KTAB);
         ktab.addEntry(service, "pass4".toCharArray(), 4, true);
         ktab.save();
-        kdc.addPrincipal("host/" + server, "pass4".toCharArray());
+        kdc.addPrincipal(serviceName, "pass4".toCharArray());
 
         c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
-        c.startAsClient("host/" + server, GSSUtil.GSS_KRB5_MECH_OID);
+        c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID);
         c.doAs(new JsseClientAction(), null);
 
         // Permission checking check. Please note this is highly
@@ -199,6 +211,14 @@
             sslSocket.setEnabledCipherSuites(enabledSuites);
             // Should check for exception if enabledSuites is not supported
 
+            if (sniHostname != null) {
+                List<SNIServerName> serverNames = new ArrayList<>();
+                serverNames.add(new SNIHostName(sniHostname));
+                SSLParameters params = sslSocket.getSSLParameters();
+                params.setServerNames(serverNames);
+                sslSocket.setSSLParameters(params);
+            }
+
             BufferedReader in = new BufferedReader(new InputStreamReader(
                 sslSocket.getInputStream()));
             BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
@@ -242,6 +262,14 @@
             sslServerSocket.setEnabledCipherSuites(enabledSuites);
             // Should check for exception if enabledSuites is not supported
 
+            if (sniMatcherPattern != null) {
+                List<SNIMatcher> matchers = new ArrayList<>();
+                matchers.add(SNIHostName.createSNIMatcher(sniMatcherPattern));
+                SSLParameters params = sslServerSocket.getSSLParameters();
+                params.setSNIMatchers(matchers);
+                sslServerSocket.setSSLParameters(params);
+            }
+
             while (loopCount++ < LOOP_LIMIT) {
                 System.out.println("Waiting for incoming connection...");
 
--- a/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/sun/security/pkcs11/KeyStore/SecretKeysBasic.sh	Tue Oct 08 14:57:32 2013 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2008, 2012, 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
@@ -143,7 +143,8 @@
 cd ${TESTSRC}
 ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} \
 	-DDIR=${TESTSRC}${FS}BasicData${FS} \
-        -classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
+        -classpath \
+        ${TESTCLASSES}${PS}${TESTCLASSES}${FS}..${PS}${TESTSRC}${FS}loader.jar \
         -DCUSTOM_DB_DIR=${TESTCLASSES} \
         -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}BasicData${FS}p11-${token}.txt \
 	-DNO_DEFAULT=true \
--- a/test/sun/security/provider/SecureRandom/StrongSecureRandom.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/sun/security/provider/SecureRandom/StrongSecureRandom.java	Tue Oct 08 14:57:32 2013 -0700
@@ -120,7 +120,14 @@
 
     private static void testStrongInstance(boolean expected) throws Exception {
 
-        boolean result = (SecureRandom.getStrongSecureRandom() != null);
+        boolean result;
+
+        try {
+            SecureRandom.getInstanceStrong();
+            result = true;
+        } catch (NoSuchAlgorithmException e) {
+            result = false;
+        }
 
         if (expected != result) {
             throw new Exception("Received: " + result);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/DHKeyExchange/DHEKeySizing.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,477 @@
+/*
+ * 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 6956398
+ * @summary make ephemeral DH key match the length of the certificate key
+ * @run main/othervm
+ *      DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
+ *      DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
+ *      DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
+ *      DHEKeySizing SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA true 1318 75
+ *
+ * @run main/othervm
+ *      DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 292 75
+ *
+ * @run main/othervm
+ *      DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA  false 1510 139
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
+ *      DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA  false 1414 107
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
+ *      DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA  false 1894 267
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
+ *      DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA  false 1510 139
+ *
+ * @run main/othervm
+ *      DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5  false 484 139
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=legacy
+ *      DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5  false 388 107
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=matched
+ *      DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5  false 484 139
+ * @run main/othervm -Djdk.tls.ephemeralDHKeySize=1024
+ *      DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5  false 484 139
+ */
+
+/*
+ * This is a simple hack to test key sizes of Diffie-Hellman key exchanging
+ * during SSL/TLS handshaking.
+ *
+ * The record length of DH ServerKeyExchange and ClientKeyExchange.
+ * ServerKeyExchange message are wrapped in ServerHello series messages, which
+ * contains ServerHello, Certificate and ServerKeyExchange message.
+ *
+ *    struct {
+ *        opaque dh_p<1..2^16-1>;
+ *        opaque dh_g<1..2^16-1>;
+ *        opaque dh_Ys<1..2^16-1>;
+ *    } ServerDHParams;     // Ephemeral DH parameters
+ *
+ *    struct {
+ *        select (PublicValueEncoding) {
+ *            case implicit: struct { };
+ *            case explicit: opaque dh_Yc<1..2^16-1>;
+ *        } dh_public;
+ *    } ClientDiffieHellmanPublic;
+ *
+ * Fomr above structures, it is clear that if the DH key size increasing 128
+ * bits (16 bytes), the ServerHello series messages increases 48 bytes
+ * (becuase dh_p, dh_g and dh_Ys each increase 16 bytes) and ClientKeyExchange
+ * increases 16 bytes (because of the size increasing of dh_Yc).
+ *
+ * Here is a summary of the record length in the test case.
+ *
+ *            |  ServerHello Series  |  ClientKeyExchange | ServerHello Anon
+ *   512-bit  |          1318 bytes  |           75 bytes |        292 bytes
+ *   768-bit  |          1414 bytes  |          107 bytes |        388 bytes
+ *  1024-bit  |          1510 bytes  |          139 bytes |        484 bytes
+ *  2048-bit  |          1894 bytes  |          267 bytes |        484 bytes
+ */
+
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.nio.*;
+import java.security.KeyStore;
+import java.security.KeyFactory;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.*;
+import java.security.interfaces.*;
+import java.util.Base64;
+
+public class DHEKeySizing {
+
+    private static boolean debug = true;
+
+    private SSLContext sslc;
+    private SSLEngine ssle1;    // client
+    private SSLEngine ssle2;    // server
+
+    private ByteBuffer appOut1;         // write side of ssle1
+    private ByteBuffer appIn1;          // read side of ssle1
+    private ByteBuffer appOut2;         // write side of ssle2
+    private ByteBuffer appIn2;          // read side of ssle2
+
+    private ByteBuffer oneToTwo;        // "reliable" transport ssle1->ssle2
+    private ByteBuffer twoToOne;        // "reliable" transport ssle2->ssle1
+
+    /*
+     * Where do we find the keystores?
+     */
+    // Certificates and key used in the test.
+    static String trustedCertStr =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIC8jCCAdqgAwIBAgIEUjkuRzANBgkqhkiG9w0BAQUFADA7MR0wGwYDVQQLExRT\n" +
+        "dW5KU1NFIFRlc3QgU2VyaXZjZTENMAsGA1UEChMESmF2YTELMAkGA1UEBhMCVVMw\n" +
+        "HhcNMTMwOTE4MDQzODMxWhcNMTMxMjE3MDQzODMxWjA7MR0wGwYDVQQLExRTdW5K\n" +
+        "U1NFIFRlc3QgU2VyaXZjZTENMAsGA1UEChMESmF2YTELMAkGA1UEBhMCVVMwggEi\n" +
+        "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCO+IGeaskJAvEcYc7pCl9neK3E\n" +
+        "a28fwWLtChufYNaC9hQfZlUdETWYjV7fZJVJKT/oLzdDNMWuVA0LKXArpI3thLNK\n" +
+        "QLXisdF9hKPlZRDazACL9kWUUtJ0FzpEySK4e8wW/z9FuU6e6iO19FbjxAfInJqk\n" +
+        "3EDiEhB5g73S2vtvPCxgq2DvWw9TDl/LIqdKG2JCS93koXCCaHmQ7MrIOqHPd+8r\n" +
+        "RbGpatXT9qyHKppUv9ATxVygO4rA794mgCFxpT+fkhz+NEB0twTkM65T1hnnOv5n\n" +
+        "ZIxkcjBggt85UlZtnP3b9P7SYxsWIa46Oc38Od2f3YejfVg6B+PqPgWNl3+/AgMB\n" +
+        "AAEwDQYJKoZIhvcNAQEFBQADggEBAAlrP6DFLRPSy0IgQhcI2i56tR/na8pezSte\n" +
+        "ZHcCdaCZPDy4UP8mpLJ9QCjEB5VJv8hPm4xdK7ULnKGOGHgYqDpV2ZHvQlhV1woQ\n" +
+        "TZGb/LM3c6kAs0j4j9KM2fq3iYUYexjIkS1KzsziflxMM6igS9BRMBR2LQyU+cYq\n" +
+        "YEsFzkF7Aj2ET4v/+tgot9mRr2NioJcaJkdsPDpMU3IKB1cczfu+OuLQ/GCG0Fqu\n" +
+        "6ijCeCqfnaAbemHbJeVZZ6Qgka3uC2YMntLBmLkhqEo1d9zGYLoh7oWL77y5ibQZ\n" +
+        "LK5/H/zikcu579TWjlDHcqL3arCwBcrtsjSaPrRSWMrWV/6c0qw=\n" +
+        "-----END CERTIFICATE-----";
+
+    // Private key in the format of PKCS#8
+    static String targetPrivateKey =
+        "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCO+IGeaskJAvEc\n" +
+        "Yc7pCl9neK3Ea28fwWLtChufYNaC9hQfZlUdETWYjV7fZJVJKT/oLzdDNMWuVA0L\n" +
+        "KXArpI3thLNKQLXisdF9hKPlZRDazACL9kWUUtJ0FzpEySK4e8wW/z9FuU6e6iO1\n" +
+        "9FbjxAfInJqk3EDiEhB5g73S2vtvPCxgq2DvWw9TDl/LIqdKG2JCS93koXCCaHmQ\n" +
+        "7MrIOqHPd+8rRbGpatXT9qyHKppUv9ATxVygO4rA794mgCFxpT+fkhz+NEB0twTk\n" +
+        "M65T1hnnOv5nZIxkcjBggt85UlZtnP3b9P7SYxsWIa46Oc38Od2f3YejfVg6B+Pq\n" +
+        "PgWNl3+/AgMBAAECggEAPdb5Ycc4m4A9QBSCRcRpzbyiFLKPh0HDg1n65q4hOtYr\n" +
+        "kAVYTVFTSF/lqGS+Ob3w2YIKujQKSUQrvCc5UHdFuHXMgxKIWbymK0+DAMb9SlYw\n" +
+        "6lkkcWp9gx9E4dnJ/df2SAAxovvrKMuHlL1SFASHhVtPfH2URvSfUaANLDXxyYOs\n" +
+        "8BX0Nr6wazhWjLjXo9yIGnKSvFfB8XisYcA78kEgas43zhmIGCDPqaYyyffOfRbx\n" +
+        "pM1KNwGmlN86iWR1CbwA/wwhcMySWQueS+s7cHbpRqZIYJF9jEeELiwi0vxjealS\n" +
+        "EMuHYedIRFMWaDIq9XyjrvXamHb0Z25jlXBNZHaM0QKBgQDE9adl+zAezR/n79vw\n" +
+        "0XiX2Fx1UEo3ApZHuoA2Q/PcBk+rlKqqQ3IwTcy6Wo648wK7v6Nq7w5nEWcsf0dU\n" +
+        "QA2Ng/AJEev/IfF34x7sKGYxtk1gcE0EuSBA3R+ocEZxnNw1Ryd5nUU24s8d4jCP\n" +
+        "Mkothnyaim+zE2raDlEtVc0CaQKBgQC509av+02Uq5oMjzbQp5PBJfQFjATOQT15\n" +
+        "eefYnVYurkQ1kcVfixkrO2ORhg4SjmI2Z5hJDgGtXdwgidpzkad+R2epS5qLMyno\n" +
+        "lQVpY6bMpEZ7Mos0yQygxnm8uNohEcTExOe+nP5fNJVpzBsGmfeyYOhnPQlf6oqf\n" +
+        "0cHizedb5wKBgQC/l5LyMil6HOGHlhzmIm3jj7VI7QR0hJC5T6N+phVml8ESUDjA\n" +
+        "DYHbmSKouISTRtkG14FY+RiSjCxH7bvuKazFV2289PETquogTA/9e8MFYqfcQwG4\n" +
+        "sXi9gBxWlnj/9a2EKiYtOB5nKLR/BlNkSHA93tAA6N+FXEMZwMmYhxk42QKBgAuY\n" +
+        "HQgD3PZOsqDf+qKQIhbmAFCsSMx5o5VFtuJ8BpmJA/Z3ruHkMuDQpsi4nX4o5hXQ\n" +
+        "5t6AAjjH52kcUMXvK40kdWJJtk3DFnVNfvXxYsHX6hHbuHXFqYUKfSP6QJnZmvZP\n" +
+        "9smcz/4usLfWJUWHK740b6upUkFqx9Vq5/b3s9y3AoGAdM5TW7LkkOFsdMGVAUzR\n" +
+        "9iXmCWElHTK2Pcp/3yqDBHSfiQx6Yp5ANyPnE9NBM0yauCfOyBB2oxLO4Rdv3Rqk\n" +
+        "9V9kyR/YAGr7dJaPcQ7pZX0OpkzgueAOJYPrx5VUzPYUtklYV1ycFZTfKlpFCxT+\n" +
+        "Ei6KUo0NXSdUIcB4yib1J10=";
+
+    static char passphrase[] = "passphrase".toCharArray();
+
+    /*
+     * Majority of the test case is here, setup is done below.
+     */
+
+    private void createSSLEngines() throws Exception {
+        ssle1 = sslc.createSSLEngine("client", 1);
+        ssle1.setUseClientMode(true);
+
+        ssle2 = sslc.createSSLEngine("server", 2);
+        ssle2.setUseClientMode(false);
+    }
+
+    private boolean isHandshaking(SSLEngine e) {
+        return (e.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING);
+    }
+
+    private void checkResult(ByteBuffer bbIn, ByteBuffer bbOut,
+            SSLEngineResult result,
+            Status status, HandshakeStatus hsStatus,
+            int consumed, int produced)
+            throws Exception {
+
+        if ((status != null) && (result.getStatus() != status)) {
+            throw new Exception("Unexpected Status: need = " + status +
+                " got = " + result.getStatus());
+        }
+
+        if ((hsStatus != null) && (result.getHandshakeStatus() != hsStatus)) {
+            throw new Exception("Unexpected hsStatus: need = " + hsStatus +
+                " got = " + result.getHandshakeStatus());
+        }
+
+        if ((consumed != -1) && (consumed != result.bytesConsumed())) {
+            throw new Exception("Unexpected consumed: need = " + consumed +
+                " got = " + result.bytesConsumed());
+        }
+
+        if ((produced != -1) && (produced != result.bytesProduced())) {
+            throw new Exception("Unexpected produced: need = " + produced +
+                " got = " + result.bytesProduced());
+        }
+
+        if ((consumed != -1) && (bbIn.position() != result.bytesConsumed())) {
+            throw new Exception("Consumed " + bbIn.position() +
+                " != " + consumed);
+        }
+
+        if ((produced != -1) && (bbOut.position() != result.bytesProduced())) {
+            throw new Exception("produced " + bbOut.position() +
+                " != " + produced);
+        }
+    }
+
+    private void test(String cipherSuite, boolean exportable,
+            int lenServerKeyEx, int lenClientKeyEx) throws Exception {
+
+        createSSLEngines();
+        createBuffers();
+
+        SSLEngineResult result1;        // ssle1's results from last operation
+        SSLEngineResult result2;        // ssle2's results from last operation
+
+        String[] suites = new String [] {cipherSuite};
+
+        ssle1.setEnabledCipherSuites(suites);
+        ssle2.setEnabledCipherSuites(suites);
+
+        log("======================================");
+        log("===================");
+        log("client hello");
+        result1 = ssle1.wrap(appOut1, oneToTwo);
+        checkResult(appOut1, oneToTwo, result1,
+            Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
+        oneToTwo.flip();
+
+        result2 = ssle2.unwrap(oneToTwo, appIn2);
+        checkResult(oneToTwo, appIn2, result2,
+            Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0);
+        runDelegatedTasks(ssle2);
+        oneToTwo.compact();
+
+        log("===================");
+        log("ServerHello");
+        result2 = ssle2.wrap(appOut2, twoToOne);
+        checkResult(appOut2, twoToOne, result2,
+            Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
+        twoToOne.flip();
+
+        log("Message length of ServerHello series: " + twoToOne.remaining());
+        if (lenServerKeyEx != twoToOne.remaining()) {
+            throw new Exception(
+                "Expected to generate ServerHello series messages of " +
+                lenServerKeyEx + " bytes, but not " + twoToOne.remaining());
+        }
+
+        result1 = ssle1.unwrap(twoToOne, appIn1);
+        checkResult(twoToOne, appIn1, result1,
+            Status.OK, HandshakeStatus.NEED_TASK, result2.bytesProduced(), 0);
+        runDelegatedTasks(ssle1);
+        twoToOne.compact();
+
+        log("===================");
+        log("Key Exchange");
+        result1 = ssle1.wrap(appOut1, oneToTwo);
+        checkResult(appOut1, oneToTwo, result1,
+            Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
+        oneToTwo.flip();
+
+        log("Message length of ClientKeyExchange: " + oneToTwo.remaining());
+        if (lenClientKeyEx != oneToTwo.remaining()) {
+            throw new Exception(
+                "Expected to generate ClientKeyExchange message of " +
+                lenClientKeyEx + " bytes, but not " + oneToTwo.remaining());
+        }
+        result2 = ssle2.unwrap(oneToTwo, appIn2);
+        checkResult(oneToTwo, appIn2, result2,
+            Status.OK, HandshakeStatus.NEED_TASK, result1.bytesProduced(), 0);
+        runDelegatedTasks(ssle2);
+        oneToTwo.compact();
+
+        log("===================");
+        log("Client CCS");
+        result1 = ssle1.wrap(appOut1, oneToTwo);
+        checkResult(appOut1, oneToTwo, result1,
+            Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
+        oneToTwo.flip();
+
+        result2 = ssle2.unwrap(oneToTwo, appIn2);
+        checkResult(oneToTwo, appIn2, result2,
+            Status.OK, HandshakeStatus.NEED_UNWRAP,
+            result1.bytesProduced(), 0);
+        oneToTwo.compact();
+
+        log("===================");
+        log("Client Finished");
+        result1 = ssle1.wrap(appOut1, oneToTwo);
+        checkResult(appOut1, oneToTwo, result1,
+            Status.OK, HandshakeStatus.NEED_UNWRAP, 0, -1);
+        oneToTwo.flip();
+
+        result2 = ssle2.unwrap(oneToTwo, appIn2);
+        checkResult(oneToTwo, appIn2, result2,
+            Status.OK, HandshakeStatus.NEED_WRAP,
+            result1.bytesProduced(), 0);
+        oneToTwo.compact();
+
+        log("===================");
+        log("Server CCS");
+        result2 = ssle2.wrap(appOut2, twoToOne);
+        checkResult(appOut2, twoToOne, result2,
+            Status.OK, HandshakeStatus.NEED_WRAP, 0, -1);
+        twoToOne.flip();
+
+        result1 = ssle1.unwrap(twoToOne, appIn1);
+        checkResult(twoToOne, appIn1, result1,
+            Status.OK, HandshakeStatus.NEED_UNWRAP, result2.bytesProduced(), 0);
+        twoToOne.compact();
+
+        log("===================");
+        log("Server Finished");
+        result2 = ssle2.wrap(appOut2, twoToOne);
+        checkResult(appOut2, twoToOne, result2,
+            Status.OK, HandshakeStatus.FINISHED, 0, -1);
+        twoToOne.flip();
+
+        result1 = ssle1.unwrap(twoToOne, appIn1);
+        checkResult(twoToOne, appIn1, result1,
+            Status.OK, HandshakeStatus.FINISHED, result2.bytesProduced(), 0);
+        twoToOne.compact();
+
+        log("===================");
+        log("Check Session/Ciphers");
+        String cs = ssle1.getSession().getCipherSuite();
+        if (!cs.equals(suites[0])) {
+            throw new Exception("suites not equal: " + cs + "/" + suites[0]);
+        }
+
+        cs = ssle2.getSession().getCipherSuite();
+        if (!cs.equals(suites[0])) {
+            throw new Exception("suites not equal: " + cs + "/" + suites[0]);
+        }
+
+        log("===================");
+        log("Done with SSL/TLS handshaking");
+    }
+
+    public static void main(String args[]) throws Exception {
+        if (args.length != 4) {
+            System.out.println(
+                "Usage: java DHEKeySizing cipher-suite " +
+                "exportable(true|false)\n" +
+                "    size-of-server-hello-record size-of-client-key-exchange");
+            throw new Exception("Incorrect usage!");
+        }
+
+        (new DHEKeySizing()).test(args[0],
+                Boolean.parseBoolean(args[1]),
+                Integer.parseInt(args[2]),
+                Integer.parseInt(args[3]));
+        System.out.println("Test Passed.");
+    }
+
+    /*
+     * **********************************************************
+     * Majority of the test case is above, below is just setup stuff
+     * **********************************************************
+     */
+
+    public DHEKeySizing() throws Exception {
+        sslc = getSSLContext();
+    }
+
+    /*
+     * Create an initialized SSLContext to use for this test.
+     */
+    private SSLContext getSSLContext() throws Exception {
+
+        // generate certificate from cert string
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+        // create a key store
+        KeyStore ts = KeyStore.getInstance("JKS");
+        KeyStore ks = KeyStore.getInstance("JKS");
+        ts.load(null, null);
+        ks.load(null, null);
+
+        // import the trused cert
+        ByteArrayInputStream is =
+                    new ByteArrayInputStream(trustedCertStr.getBytes());
+        Certificate trusedCert = cf.generateCertificate(is);
+        is.close();
+        ts.setCertificateEntry("rsa-trusted-2048", trusedCert);
+
+        // generate the private key.
+        String keySpecStr = targetPrivateKey;
+        PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+                            Base64.getMimeDecoder().decode(keySpecStr));
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKey priKey = (RSAPrivateKey)kf.generatePrivate(priKeySpec);
+
+        Certificate[] chain = new Certificate[1];
+        chain[0] = trusedCert;
+
+        // import the key entry.
+        ks.setKeyEntry("rsa-key-2048", priKey, passphrase, chain);
+
+        // create SSL context
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+        kmf.init(ks, passphrase);
+
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+        tmf.init(ts);
+
+        SSLContext sslCtx = SSLContext.getInstance("TLS");
+        sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+        return sslCtx;
+    }
+
+    private void createBuffers() {
+        // Size the buffers as appropriate.
+
+        SSLSession session = ssle1.getSession();
+        int appBufferMax = session.getApplicationBufferSize();
+        int netBufferMax = session.getPacketBufferSize();
+
+        appIn1 = ByteBuffer.allocateDirect(appBufferMax + 50);
+        appIn2 = ByteBuffer.allocateDirect(appBufferMax + 50);
+
+        oneToTwo = ByteBuffer.allocateDirect(netBufferMax);
+        twoToOne = ByteBuffer.allocateDirect(netBufferMax);
+
+        appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes());
+        appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes());
+
+        log("AppOut1 = " + appOut1);
+        log("AppOut2 = " + appOut2);
+        log("");
+    }
+
+    private static void runDelegatedTasks(SSLEngine engine) throws Exception {
+
+        Runnable runnable;
+        while ((runnable = engine.getDelegatedTask()) != null) {
+            log("running delegated task...");
+            runnable.run();
+        }
+    }
+
+    private static void log(String str) {
+        if (debug) {
+            System.out.println(str);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/tools/keytool/StorePasswords.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,186 @@
+/*
+ * 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 8008296
+ * @summary Store and retrieve user passwords using PKCS#12 keystore
+ */
+
+import java.io.*;
+import java.security.*;
+import java.util.*;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+/*
+ * Store and retrieve passwords protected by a selection of PBE algorithms,
+ * using a PKCS#12 keystore.
+ */
+public class StorePasswords {
+
+    private static final String[] PBE_ALGORITHMS = new String[] {
+        "default PBE algorithm",
+        "PBEWithMD5AndDES",
+        "PBEWithSHA1AndDESede",
+        "PBEWithSHA1AndRC2_40",
+        "PBEWithSHA1AndRC2_128",
+        "PBEWithSHA1AndRC4_40",
+        "PBEWithSHA1AndRC4_128",
+        "PBEWithHmacSHA1AndAES_128",
+        "PBEWithHmacSHA224AndAES_128",
+        "PBEWithHmacSHA256AndAES_128",
+        "PBEWithHmacSHA384AndAES_128",
+        "PBEWithHmacSHA512AndAES_128",
+        "PBEWithHmacSHA1AndAES_256",
+        "PBEWithHmacSHA224AndAES_256",
+        "PBEWithHmacSHA256AndAES_256",
+        "PBEWithHmacSHA384AndAES_256",
+        "PBEWithHmacSHA512AndAES_256"
+    };
+
+    private static final String KEYSTORE = "mykeystore.p12";
+    private static final char[] KEYSTORE_PWD = "changeit".toCharArray();
+    private static final char[] ENTRY_PWD = "protectit".toCharArray();
+    private static final char[] USER_PWD = "hello1".toCharArray();
+
+    public static void main(String[] args) throws Exception {
+
+        new File(KEYSTORE).delete();
+
+        int storeCount = store();
+        int recoverCount = recover();
+
+        if (recoverCount != storeCount) {
+            throw new Exception("Stored " + storeCount + " user passwords, " +
+                "recovered " + recoverCount + " user passwords");
+        }
+        System.out.println("\nStored " + storeCount + " user passwords, " +
+            "recovered " + recoverCount + " user passwords");
+    }
+
+    private static int store() throws Exception {
+        int count = 0;
+        // Load an empty PKCS#12 keystore
+        KeyStore keystore = KeyStore.getInstance("PKCS12");
+        System.out.println("\nLoading PKCS#12 keystore...");
+        keystore.load(null, null);
+
+        // Derive a PBE key from the password
+        PBEKeySpec keySpec = new PBEKeySpec(USER_PWD);
+        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBE");
+        SecretKey key = factory.generateSecret(keySpec);
+        PBEParameterSpec specWithEightByteSalt =
+            new PBEParameterSpec("NaClNaCl".getBytes(), 1024);
+
+        // Store the user password in a keystore entry (for each algorithm)
+        for (String algorithm : PBE_ALGORITHMS) {
+
+            try {
+                System.out.println("Storing user password '" +
+                    new String(USER_PWD) + "' (protected by " + algorithm +
+                    ")");
+
+                if (algorithm.equals("default PBE algorithm")) {
+                     keystore.setKeyEntry(
+                         "this entry is protected by " + algorithm, key,
+                         ENTRY_PWD, null);
+                } else {
+                    keystore.setEntry(
+                        "this entry is protected by " + algorithm,
+                        new KeyStore.SecretKeyEntry(key),
+                        new KeyStore.PasswordProtection(ENTRY_PWD, algorithm,
+                            null));
+                }
+                count++;
+
+            } catch (KeyStoreException e) {
+                Throwable inner = e.getCause();
+                if (inner instanceof UnrecoverableKeyException) {
+                    Throwable inner2 = inner.getCause();
+                    if (inner2 instanceof InvalidAlgorithmParameterException) {
+                        System.out.println("...re-trying due to: " +
+                            inner2.getMessage());
+
+                        // Some PBE algorithms demand an 8-byte salt
+                        keystore.setEntry(
+                            "this entry is protected by " + algorithm,
+                            new KeyStore.SecretKeyEntry(key),
+                            new KeyStore.PasswordProtection(ENTRY_PWD,
+                                algorithm, specWithEightByteSalt));
+                        count++;
+
+                    } else if (inner2  instanceof InvalidKeyException) {
+                        System.out.println("...skipping due to: " +
+                            inner2.getMessage());
+                        // Unsupported crypto keysize
+                        continue;
+                    }
+                } else {
+                    throw e;
+                }
+            }
+        }
+
+        // Store the PKCS#12 keystore
+        System.out.println("Storing PKCS#12 keystore to: " + KEYSTORE);
+        keystore.store(new FileOutputStream(KEYSTORE), KEYSTORE_PWD);
+
+        return count;
+    }
+
+    private static int recover() throws Exception {
+        int count = 0;
+        // Load the PKCS#12 keystore
+        KeyStore keystore = KeyStore.getInstance("PKCS12");
+        System.out.println("\nLoading PKCS#12 keystore from: " + KEYSTORE);
+        keystore.load(new FileInputStream(KEYSTORE), KEYSTORE_PWD);
+
+        SecretKey key;
+        SecretKeyFactory factory;
+        PBEKeySpec keySpec;
+
+        // Retrieve each user password from the keystore
+        for (String algorithm : PBE_ALGORITHMS) {
+            key = (SecretKey) keystore.getKey("this entry is protected by " +
+                algorithm, ENTRY_PWD);
+
+            if (key != null) {
+                count++;
+                factory = SecretKeyFactory.getInstance(key.getAlgorithm());
+                keySpec =
+                    (PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class);
+                char[] pwd = keySpec.getPassword();
+                System.out.println("Recovered user password '" +
+                     new String(pwd) + "' (protected by " + algorithm + ")");
+
+                if (!Arrays.equals(USER_PWD, pwd)) {
+                    throw new Exception("Failed to recover the user password " +
+                        "protected by " + algorithm);
+                }
+            }
+        }
+
+        return count;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/tools/keytool/StorePasswordsByShell.sh	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,140 @@
+#
+# 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 8008296
+# @summary confirm that keytool correctly imports user passwords
+#
+# @run shell StorePasswordsByShell.sh
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+if [ "${TESTSRC}" = "" ] ; then
+   TESTSRC="."
+fi 
+  
+if [ "${TESTCLASSES}" = "" ] ; then
+   TESTCLASSES="." 
+fi
+  
+if [ "${TESTJAVA}" = "" ] ; then
+   echo "TESTJAVA not set.  Test cannot execute."
+   echo "FAILED!!!"
+   exit 1
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS )
+    PATHSEP=":"
+    FILESEP="/"
+    ;;
+  Linux )
+    PATHSEP=":"
+    FILESEP="/"
+    ;;
+  Darwin ) 
+    PATHSEP=":"
+    FILESEP="/"
+    ;;
+  CYGWIN* )
+    PATHSEP=";"
+    FILESEP="/"
+    ;;
+  Windows* )
+    PATHSEP=";"
+    FILESEP="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+PBE_ALGORITHMS="\
+ default-PBE-algorithm \
+ PBEWithMD5AndDES \
+ PBEWithSHA1AndDESede \
+ PBEWithSHA1AndRC2_40 \
+ PBEWithSHA1AndRC2_128 
+ PBEWithSHA1AndRC4_40 \
+ PBEWithSHA1AndRC4_128 \
+ PBEWithHmacSHA1AndAES_128 \
+ PBEWithHmacSHA224AndAES_128 \
+ PBEWithHmacSHA256AndAES_128 \
+ PBEWithHmacSHA384AndAES_128 \
+ PBEWithHmacSHA512AndAES_128 \
+ PBEWithHmacSHA1AndAES_256 \
+ PBEWithHmacSHA224AndAES_256 \
+ PBEWithHmacSHA256AndAES_256 \
+ PBEWithHmacSHA384AndAES_256 \
+ PBEWithHmacSHA512AndAES_256"
+
+USER_PWD="hello1\n"
+ALIAS_PREFIX="this entry is protected by "
+COUNTER=0
+
+# cleanup
+rm mykeystore.p12 > /dev/null 2>&1
+
+echo
+for i in $PBE_ALGORITHMS; do
+
+    if [ $i = "default-PBE-algorithm" ]; then
+        KEYALG=""
+    else
+        KEYALG="-keyalg ${i}"
+    fi
+
+    if [ $COUNTER -lt 5 ]; then
+        IMPORTPASSWORD="-importpassword"
+    else
+        IMPORTPASSWORD="-importpass"
+    fi
+
+    echo "Storing user password (protected by ${i})"
+    echo "${USER_PWD}" | \
+        ${TESTJAVA}${FILESEP}bin${FILESEP}keytool ${IMPORTPASSWORD} \
+            -storetype pkcs12 -keystore mykeystore.p12 -storepass changeit \
+            -alias "${ALIAS_PREFIX}${i}" ${KEYALG} > /dev/null 2>&1
+    if [ $? -ne 0 ]; then
+        echo Error
+    else
+        echo OK
+        COUNTER=`expr ${COUNTER} + 1`
+    fi
+done
+echo
+
+COUNTER2=`${TESTJAVA}${FILESEP}bin${FILESEP}keytool -list -storetype pkcs12 \
+  -keystore mykeystore.p12 -storepass changeit | grep -c "${ALIAS_PREFIX}"`
+
+RESULT="stored ${COUNTER} user passwords, detected ${COUNTER2} user passwords"
+if [ $COUNTER -ne $COUNTER2 -o $COUNTER -lt 11 ]; then
+    echo "ERROR: $RESULT"
+    exit 1
+else
+    echo "OK: $RESULT"
+    exit 0
+fi
--- a/test/tools/launcher/DiacriticTest.java	Tue Oct 08 14:53:14 2013 -0700
+++ b/test/tools/launcher/DiacriticTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -54,7 +54,13 @@
                 "}\n";
         ArrayList<String> content = new ArrayList<>();
         content.add(source);
-        createFile(sourceFile, content);
+        try {
+            createFile(sourceFile, content);
+        } catch (java.nio.file.InvalidPathException ipe) {
+            System.out.println("The locale or file system is configured in a way " +
+                               "that prevents file creation. Real testing impossible.");
+            return;
+        }
 
         HashMap<String, String> env = new HashMap<>();
         env.put("LC_CTYPE", "UTF-8");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/launcher/I18NArgTest.java	Tue Oct 08 14:57:32 2013 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8016110
+ * @summary verify Japanese character in an argument are treated correctly
+ * @compile -XDignore.symbol.file I18NArgTest.java
+ * @run main I18NArgTest
+ */
+import java.io.IOException;
+
+public class I18NArgTest extends TestHelper {
+    public static void main(String... args) throws IOException {
+        if (!isWindows) {
+            return;
+        }
+        if (!"MS932".equals(System.getProperty("sun.jnu.encoding"))) {
+            System.err.println("MS932 encoding not set, test skipped");
+            return;
+        }
+        if (args.length == 0) {
+            execTest(0x30bd); // MS932 Katakana SO, 0x835C
+        } else {
+            testCharacters(args);
+        }
+    }
+    static void execTest(int unicodeValue) {
+        String hexValue = Integer.toHexString(unicodeValue);
+        String unicodeStr = Character.toString((char)unicodeValue);
+        execTest("\"" + unicodeStr + "\"", hexValue);
+        execTest("\\" + unicodeStr + "\\", hexValue);
+        execTest(" " + unicodeStr + " ", hexValue);
+        execTest("'" + unicodeStr + "'", hexValue);
+        execTest("\t" + unicodeStr + "\t", hexValue);
+        execTest("*" + unicodeStr + "*", hexValue);
+        execTest("?" + unicodeStr + "?", hexValue);
+
+        execTest("\"" + unicodeStr + unicodeStr + "\"", hexValue + hexValue);
+        execTest("\\" + unicodeStr + unicodeStr + "\\", hexValue + hexValue);
+        execTest(" " + unicodeStr + unicodeStr + " ", hexValue + hexValue);
+        execTest("'" + unicodeStr + unicodeStr + "'", hexValue + hexValue);
+        execTest("\t" + unicodeStr + unicodeStr + "\t", hexValue + hexValue);
+        execTest("*" + unicodeStr + unicodeStr + "*", hexValue + hexValue);
+        execTest("?" + unicodeStr + unicodeStr + "?", hexValue + hexValue);
+
+        execTest("\"" + unicodeStr + "a" + unicodeStr + "\"", hexValue + "61" + hexValue);
+        execTest("\\" + unicodeStr + "a" + unicodeStr + "\\", hexValue + "61" + hexValue);
+        execTest(" " + unicodeStr + "a" + unicodeStr + " ", hexValue + "61"+ hexValue);
+        execTest("'" + unicodeStr + "a" + unicodeStr + "'", hexValue + "61"+ hexValue);
+        execTest("\t" + unicodeStr + "a" + unicodeStr + "\t", hexValue + "61"+ hexValue);
+        execTest("*" + unicodeStr + "a" + unicodeStr + "*", hexValue + "61"+ hexValue);
+        execTest("?" + unicodeStr + "a" + unicodeStr + "?", hexValue + "61"+ hexValue);
+
+        execTest("\"" + unicodeStr + "\u00b1" + unicodeStr + "\"", hexValue + "b1" + hexValue);
+        execTest("\\" + unicodeStr + "\u00b1" + unicodeStr + "\\", hexValue + "b1" + hexValue);
+        execTest(" " + unicodeStr + "\u00b1" + unicodeStr + " ", hexValue + "b1"+ hexValue);
+        execTest("'" + unicodeStr + "\u00b1" + unicodeStr + "'", hexValue + "b1"+ hexValue);
+        execTest("\t" + unicodeStr + "\u00b1" + unicodeStr + "\t", hexValue + "b1"+ hexValue);
+        execTest("*" + unicodeStr + "\u00b1" + unicodeStr + "*", hexValue + "b1"+ hexValue);
+        execTest("?" + unicodeStr + "\u00b1" + unicodeStr + "?", hexValue + "b1"+ hexValue);
+    }
+    static void execTest(String unicodeStr, String hexValue) {
+        TestResult tr = doExec(javaCmd,
+                "-Dtest.src=" + TEST_SOURCES_DIR.getAbsolutePath(),
+                "-Dtest.classes=" + TEST_CLASSES_DIR.getAbsolutePath(),
+                "-cp", TEST_CLASSES_DIR.getAbsolutePath(),
+                "I18NArgTest", unicodeStr, hexValue);
+        System.out.println(tr.testOutput);
+        if (!tr.isOK()) {
+            System.err.println(tr);
+            throw new RuntimeException("test fails");
+        }
+    }
+    static void testCharacters(String... args) {
+        String input = args[0];
+        String expected = args[1];
+        String hexValue = "";
+        for (int i = 0; i < input.length(); i++) {
+            hexValue = hexValue.concat(Integer.toHexString((int)input.charAt(i)));
+        }
+        System.out.println("input:" + input);
+        System.out.println("expected:" + expected);
+        System.out.println("obtained:" + hexValue);
+        if (!hexValue.contains(expected)) {
+            String message = "Error: output does not contain expected value" +
+                "expected:" + expected + " obtained:" + hexValue;
+            throw new RuntimeException(message);
+        }
+    }
+}