Merge
authorbrutisso
Wed, 18 May 2011 13:19:32 +0200
changeset 9937 4f843e4c0cf6
parent 9726 4a05062d8c4d (diff)
parent 9936 59dac2950cc7 (current diff)
child 9940 a9287f2151fb
Merge
--- a/.hgtags	Tue May 17 00:56:01 2011 -0700
+++ b/.hgtags	Wed May 18 13:19:32 2011 +0200
@@ -116,3 +116,4 @@
 955488f34ca418f6cdab843d61c20d2c615637d9 jdk7-b139
 f4298bc3f4b6baa315643be06966f09684290068 jdk7-b140
 5d86d0c7692e8f4a58d430d68c03594e2d3403b3 jdk7-b141
+92bf0655022d4187e9b49c1400f98fb3392a4630 jdk7-b142
--- a/.hgtags-top-repo	Tue May 17 00:56:01 2011 -0700
+++ b/.hgtags-top-repo	Wed May 18 13:19:32 2011 +0200
@@ -116,3 +116,4 @@
 7ed6d0b9aaa12320832a7ddadb88d6d8d0dda4c1 jdk7-b139
 dcfe74f1c6553c556e7d361c30b0b614eb5e40f6 jdk7-b140
 c6569c5585851dfd39b8de8e021c3c312f51af12 jdk7-b141
+cfbbdb77eac0397b03eb99ee2e07ea00e0a7b81e jdk7-b142
--- a/Makefile	Tue May 17 00:56:01 2011 -0700
+++ b/Makefile	Wed May 18 13:19:32 2011 +0200
@@ -25,6 +25,34 @@
 
 BUILD_PARENT_DIRECTORY=.
 
+# Basename of any originally supplied ALT_OUTPUTDIR directory
+ifndef ORIG_OUTPUTDIR_BASENAME
+  ifdef ALT_OUTPUTDIR
+    ORIG_OUTPUTDIR_BASENAME := $(shell basename $(ALT_OUTPUTDIR))
+  else
+    ORIG_OUTPUTDIR_BASENAME  = $(PLATFORM)-$(ARCH)
+  endif
+endif
+export ORIG_OUTPUTDIR_BASENAME
+
+# The three possible directories created for output (3 build flavors)
+OUTPUTDIR_BASENAME-          = $(ORIG_OUTPUTDIR_BASENAME)
+OUTPUTDIR_BASENAME-debug     = $(ORIG_OUTPUTDIR_BASENAME)-debug
+OUTPUTDIR_BASENAME-fastdebug = $(ORIG_OUTPUTDIR_BASENAME)-fastdebug
+
+# Relative path to a debug output area
+REL_JDK_OUTPUTDIR = ../$(OUTPUTDIR_BASENAME-$(DEBUG_NAME))
+
+# The created jdk image directory
+JDK_IMAGE_DIRNAME = j2sdk-image
+JDK_IMAGE_DIR     = $(OUTPUTDIR)/$(JDK_IMAGE_DIRNAME)
+ABS_JDK_IMAGE_DIR = $(ABS_OUTPUTDIR)/$(JDK_IMAGE_DIRNAME)
+
+# Relative path from an output directory to the image directory
+REL_JDK_IMAGE_DIR = ../$(OUTPUTDIR_BASENAME-$(DEBUG_NAME))/$(JDK_IMAGE_DIRNAME)
+REL_JDK_DEBUG_IMAGE_DIR = ../$(OUTPUTDIR_BASENAME-debug)/$(JDK_IMAGE_DIRNAME)
+REL_JDK_FASTDEBUG_IMAGE_DIR = ../$(OUTPUTDIR_BASENAME-fastdebug)/$(JDK_IMAGE_DIRNAME)
+
 ifndef TOPDIR
   TOPDIR:=.
 endif
@@ -98,8 +126,7 @@
 
 # Generic build of basic repo series
 generic_build_repo_series:: $(SOURCE_TIPS)
-	$(MKDIR) -p $(OUTPUTDIR)
-	$(MKDIR) -p $(OUTPUTDIR)/j2sdk-image
+	$(MKDIR) -p $(JDK_IMAGE_DIR)
 	@$(call StartTimer)
 
 ifeq ($(BUILD_LANGTOOLS), true)
@@ -146,8 +173,8 @@
 #
 #   DEBUG_NAME is fastdebug or debug
 #   ALT_OUTPUTDIR is changed to have -debug or -fastdebug suffix
-#   The resulting j2sdk-image is used by the install makefiles to create a
-#     debug install bundle jdk-*-debug-** bundle (tar or zip) 
+#   The resulting image directory (j2sdk-image) is used by the install makefiles
+#     to create a debug install bundle jdk-*-debug-** bundle (tar or zip) 
 #     which will install in the debug or fastdebug subdirectory of the
 #     normal product install area.
 #     The install process needs to know what the DEBUG_NAME is, so
@@ -160,8 +187,8 @@
 
 # Location of fresh bootdir output
 ABS_BOOTDIR_OUTPUTDIR=$(ABS_OUTPUTDIR)/bootjdk
-FRESH_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/j2sdk-image
-FRESH_DEBUG_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-$(DEBUG_NAME)/j2sdk-image
+FRESH_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/$(JDK_IMAGE_DIRNAME)
+FRESH_DEBUG_BOOTDIR=$(ABS_BOOTDIR_OUTPUTDIR)/$(REL_JDK_IMAGE_DIR)
   
 create_fresh_product_bootdir: FRC
 	$(MAKE) ALT_OUTPUTDIR=$(ABS_BOOTDIR_OUTPUTDIR) \
@@ -226,7 +253,7 @@
 
 generic_debug_build:
 	$(MAKE) \
-		ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-$(DEBUG_NAME) \
+		ALT_OUTPUTDIR=$(ABS_OUTPUTDIR)/$(REL_JDK_OUTPUTDIR) \
 	        DEBUG_NAME=$(DEBUG_NAME) \
 		GENERATE_DOCS=false \
 	        $(BOOT_CYCLE_DEBUG_SETTINGS) \
@@ -254,8 +281,6 @@
 clobber:: REPORT_BUILD_TIMES=
 clobber:: 
 	$(RM) -r $(OUTPUTDIR)/*
-	$(RM) -r $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-debug/*
-	$(RM) -r $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-fastdebug/*
 	-($(RMDIR) -p $(OUTPUTDIR) > $(DEV_NULL) 2>&1; $(TRUE))
 
 clean: clobber
@@ -489,8 +514,8 @@
 
 # Get log file of all tests run
 JDK_TO_TEST := $(shell 							\
-  if [ -d "$(ABS_OUTPUTDIR)/j2sdk-image" ] ; then 			\
-    $(ECHO) "$(ABS_OUTPUTDIR)/j2sdk-image"; 				\
+  if [ -d "$(ABS_JDK_IMAGE_DIR)" ] ; then 				\
+    $(ECHO) "$(ABS_JDK_IMAGE_DIR)"; 					\
   elif [ -d "$(ABS_OUTPUTDIR)/bin" ] ; then 				\
     $(ECHO) "$(ABS_OUTPUTDIR)"; 					\
   elif [ "$(PRODUCT_HOME)" != "" -a -d "$(PRODUCT_HOME)/bin" ] ; then 	\
--- a/corba/.hgtags	Tue May 17 00:56:01 2011 -0700
+++ b/corba/.hgtags	Wed May 18 13:19:32 2011 +0200
@@ -116,3 +116,4 @@
 60b074ec6fcf5cdf9efce22fdfb02326ed8fa2d3 jdk7-b139
 cdf5d19ec142424489549025e9c42e51f32cf688 jdk7-b140
 a58635cdd921bafef353f4864184a0481353197b jdk7-b141
+a2f340a048c88d10cbedc0504f5cf03d39925a40 jdk7-b142
--- a/hotspot/.hgtags	Tue May 17 00:56:01 2011 -0700
+++ b/hotspot/.hgtags	Wed May 18 13:19:32 2011 +0200
@@ -170,3 +170,5 @@
 d283b82966712b353fa307845a1316da42a355f4 hs21-b10
 5d07913abd59261c77f24cc04a759cb75d804099 jdk7-b141
 3aea9e9feb073f5500e031be6186666bcae89aa2 hs21-b11
+9ad1548c6b63d596c411afc35147ffd5254426d9 jdk7-b142
+9ad1548c6b63d596c411afc35147ffd5254426d9 hs21-b12
--- a/hotspot/make/hotspot_version	Tue May 17 00:56:01 2011 -0700
+++ b/hotspot/make/hotspot_version	Wed May 18 13:19:32 2011 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=21
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=12
+HS_BUILD_NUMBER=13
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/jaxp/.hgtags	Tue May 17 00:56:01 2011 -0700
+++ b/jaxp/.hgtags	Wed May 18 13:19:32 2011 +0200
@@ -116,3 +116,4 @@
 28c7c0ed2444607829ba11ad827f8d52197a2830 jdk7-b139
 c8136fd161c83917f87e93b14fa2ba3483f9be83 jdk7-b140
 e1b5ef243445bf836d095fd44866e1771ef99374 jdk7-b141
+7d067af4b25e4b7e6b28bef48527d67f8650e6c5 jdk7-b142
--- a/jaxws/.hgtags	Tue May 17 00:56:01 2011 -0700
+++ b/jaxws/.hgtags	Wed May 18 13:19:32 2011 +0200
@@ -116,3 +116,4 @@
 c025078c8362076503bb83b8e4da14ba7b347940 jdk7-b139
 82a9022c4f21b1313023c8303b557a17c4106701 jdk7-b140
 66826b0aec5a1834da3821c35cf85ac154e9b04d jdk7-b141
+0ef3ef823c39eee3d670e58027c3219cb66f0283 jdk7-b142
--- a/jaxws/jaxws.properties	Tue May 17 00:56:01 2011 -0700
+++ b/jaxws/jaxws.properties	Wed May 18 13:19:32 2011 +0200
@@ -25,8 +25,8 @@
 
 drops.master.copy.base=${drops.dir}
 
-jaxws_src.bundle.name=jdk7-jaxws2_2_4-b01-2011_04_08.zip
-jaxws_src.bundle.md5.checksum=9f35dd731c99ddb62db650aaf20e5bf4
+jaxws_src.bundle.name=jdk7-jaxws2_2_4-b02-2011_05_09.zip
+jaxws_src.bundle.md5.checksum=0972a58090e8b2735d91a2f5d1ae1964
 jaxws_src.master.bundle.dir=${drops.master.copy.base}
 jaxws_src.master.bundle.url.base=http://download.java.net/glassfish/components/jax-ws/openjdk/jdk7
 
--- a/jdk/.hgtags	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/.hgtags	Wed May 18 13:19:32 2011 +0200
@@ -116,3 +116,4 @@
 d80954a89b49fda47c0c5cace65a17f5a758b8bd jdk7-b139
 9315c733fb17ddfb9fb44be7e0ffea37bf3c727d jdk7-b140
 63eeefe118da18c75ba3d36266768cd1ccaaca6b jdk7-b141
+312612e89ece62633f4809706dec00bcd5fe7c2d jdk7-b142
--- a/jdk/make/com/sun/nio/sctp/FILES_java.gmk	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/make/com/sun/nio/sctp/FILES_java.gmk	Wed May 18 13:19:32 2011 +0200
@@ -38,7 +38,7 @@
 	com/sun/nio/sctp/SctpMultiChannel.java \
 	com/sun/nio/sctp/SctpServerChannel.java \
 	com/sun/nio/sctp/SctpSocketOption.java \
-	com/sun/nio/sctp/SctpStandardSocketOption.java \
+	com/sun/nio/sctp/SctpStandardSocketOptions.java \
 	com/sun/nio/sctp/SendFailedNotification.java \
 	com/sun/nio/sctp/ShutdownNotification.java \
 	\
--- a/jdk/make/java/management/mapfile-vers	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/make/java/management/mapfile-vers	Wed May 18 13:19:32 2011 +0200
@@ -49,6 +49,7 @@
 	    Java_sun_management_Flag_setStringValue;
 	    Java_sun_management_GarbageCollectorImpl_getCollectionCount;
 	    Java_sun_management_GarbageCollectorImpl_getCollectionTime;
+	    Java_sun_management_GarbageCollectorImpl_setNotificationEnabled;
 	    Java_sun_management_GcInfoBuilder_fillGcAttributeInfo;
 	    Java_sun_management_GcInfoBuilder_getLastGcInfo0;
 	    Java_sun_management_GcInfoBuilder_getNumGcExtAttributes;
--- a/jdk/make/java/nio/FILES_java.gmk	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/make/java/nio/FILES_java.gmk	Wed May 18 13:19:32 2011 +0200
@@ -71,7 +71,7 @@
 	java/nio/charset/CoderMalfunctionError.java \
 	java/nio/charset/CodingErrorAction.java \
 	java/nio/charset/MalformedInputException.java \
-	java/nio/charset/StandardCharset.java \
+	java/nio/charset/StandardCharsets.java \
 	java/nio/charset/UnmappableCharacterException.java \
 	\
 	java/nio/charset/spi/CharsetProvider.java \
@@ -116,7 +116,7 @@
 	java/nio/file/SimpleFileVisitor.java \
 	java/nio/file/StandardCopyOption.java \
 	java/nio/file/StandardOpenOption.java \
-	java/nio/file/StandardWatchEventKind.java \
+	java/nio/file/StandardWatchEventKinds.java \
 	java/nio/file/TempFileHelper.java \
 	java/nio/file/WatchEvent.java \
 	java/nio/file/WatchKey.java \
--- a/jdk/make/sun/rmi/rmi/Makefile	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/make/sun/rmi/rmi/Makefile	Wed May 18 13:19:32 2011 +0200
@@ -85,16 +85,21 @@
 	sun.rmi.registry.RegistryImpl \
 	sun.rmi.transport.DGCImpl
 
-ifeq ($(PLATFORM), windows)
-build: stubs
-else # PLATFORM
-ifneq ($(ARCH_DATA_MODEL), 32)
-build: stubs
-else # ARCH_DATA_MODEL
-build: stubs bin
+#
+# The java-rmi.cgi script in bin/ only gets delivered in certain situations
+#
+BUILD_TARGETS = stubs
+ifeq ($(PLATFORM), linux)
+  BUILD_TARGETS += bin
 endif
+ifeq ($(PLATFORM), solaris)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    BUILD_TARGETS += bin
+  endif
 endif
 
+build: $(BUILD_TARGETS)
+
 clean clobber:: bin.clean
 
 
--- a/jdk/make/sun/xawt/mapfile-vers	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/make/sun/xawt/mapfile-vers	Wed May 18 13:19:32 2011 +0200
@@ -158,7 +158,6 @@
         Java_sun_awt_X11_XRobotPeer_mouseReleaseImpl;
         Java_sun_awt_X11_XRobotPeer_mouseWheelImpl;
         Java_sun_awt_X11_XRobotPeer_setup;
-        Java_sun_awt_X11_XRobotPeer__1dispose;
         Java_sun_awt_X11_XToolkit_getNumberOfButtonsImpl;
         Java_java_awt_Component_initIDs;
         Java_java_awt_Container_initIDs;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import javax.management.Notification;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataView;
+import javax.management.openmbean.CompositeType;
+import java.util.Collection;
+import java.util.Collections;
+import sun.management.GarbageCollectionNotifInfoCompositeData;
+
+/**
+ * The information about a garbage collection
+ *
+ * <p>
+ * A garbage collection notification is emitted by {@link GarbageCollectorMXBean}
+ * when the Java virtual machine completes a garbage collection action
+ * The notification emitted will contain the garbage collection notification
+ * information about the status of the memory:
+ * <u1>
+ *   <li>The name of the garbage collector used perform the collection.</li>
+ *   <li>The action performed by the garbage collector.</li>
+ *   <li>The cause of the garbage collection action.</li>
+ *   <li>A {@link GcInfo} object containing some statistics about the GC cycle
+          (start time, end time) and the memory usage before and after
+          the GC cycle.</li>
+ * </u1>
+ *
+ * <p>
+ * A {@link CompositeData CompositeData} representing
+ * the {@code GarbageCollectionNotificationInfo} object
+ * is stored in the
+ * {@linkplain javax.management.Notification#setUserData userdata}
+ * of a {@linkplain javax.management.Notification notification}.
+ * The {@link #from from} method is provided to convert from
+ * a {@code CompositeData} to a {@code GarbageCollectionNotificationInfo}
+ * object. For example:
+ *
+ * <blockquote><pre>
+ *      Notification notif;
+ *
+ *      // receive the notification emitted by a GarbageCollectorMXBean and set to notif
+ *      ...
+ *
+ *      String notifType = notif.getType();
+ *      if (notifType.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
+ *          // retrieve the garbage collection notification information
+ *          CompositeData cd = (CompositeData) notif.getUserData();
+ *          GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
+ *          ....
+ *      }
+ * </pre></blockquote>
+ *
+ * <p>
+ * The type of the notification emitted by a {@code GarbageCollectorMXBean} is:
+ * <ul>
+ *   <li>A {@linkplain #GARBAGE_COLLECTION_NOTIFICATION garbage collection notification}.
+ *       <br>Used by every notification emitted by the garbage collector, the details about
+ *             the notification are provided in the {@linkplain #getGcAction action} String
+ *       <p></li>
+ * </ul>
+ **/
+
+public class GarbageCollectionNotificationInfo implements  CompositeDataView {
+
+    private final String gcName;
+    private final String gcAction;
+    private final String gcCause;
+    private final GcInfo gcInfo;
+    private final CompositeData cdata;
+
+    /**
+     * Notification type denoting that
+     * the Java virtual machine has completed a garbage collection cycle.
+     * This notification is emitted by a {@link GarbageCollectorMXBean}.
+     * The value of this notification type is
+     * {@code com.sun.management.gc.notification}.
+     */
+    public static final String GARBAGE_COLLECTION_NOTIFICATION =
+        "com.sun.management.gc.notification";
+
+    /**
+     * Constructs a {@code GarbageCollectionNotificationInfo} object.
+     *
+     * @param gcName The name of the garbage collector used to perform the collection
+     * @param gcAction The name of the action performed by the garbage collector
+     * @param gcCause The cause the garbage collection action
+     * @param gcInfo  a GcInfo object providing statistics about the GC cycle
+     */
+    public GarbageCollectionNotificationInfo(String gcName,
+                                             String gcAction,
+                                             String gcCause,
+                                             GcInfo gcInfo)  {
+        if (gcName == null) {
+            throw new NullPointerException("Null gcName");
+        }
+        if (gcAction == null) {
+            throw new NullPointerException("Null gcAction");
+        }
+        if (gcCause == null) {
+            throw new NullPointerException("Null gcCause");
+        }
+        this.gcName = gcName;
+        this.gcAction = gcAction;
+        this.gcCause = gcCause;
+        this.gcInfo = gcInfo;
+        this.cdata = new GarbageCollectionNotifInfoCompositeData(this);
+    }
+
+    GarbageCollectionNotificationInfo(CompositeData cd) {
+        GarbageCollectionNotifInfoCompositeData.validateCompositeData(cd);
+
+        this.gcName = GarbageCollectionNotifInfoCompositeData.getGcName(cd);
+        this.gcAction = GarbageCollectionNotifInfoCompositeData.getGcAction(cd);
+        this.gcCause = GarbageCollectionNotifInfoCompositeData.getGcCause(cd);
+        this.gcInfo = GarbageCollectionNotifInfoCompositeData.getGcInfo(cd);
+        this.cdata = cd;
+    }
+
+    /**
+     * Returns the name of the garbage collector used to perform the collection
+     *
+     * @return the name of the garbage collector used to perform the collection
+     */
+    public String getGcName() {
+        return gcName;
+    }
+
+    /**
+     * Returns the action of the performed by the garbage collector
+     *
+     * @return the the action of the performed by the garbage collector
+     */
+    public String getGcAction() {
+        return gcAction;
+    }
+
+    /**
+     * Returns the cause  the garbage collection
+     *
+     * @return the the cause  the garbage collection
+     */
+    public String getGcCause() {
+        return gcCause;
+    }
+
+    /**
+     * Returns the GC information related to the last garbage collection
+     *
+     * @return the GC information related to the
+     * last garbage collection
+     */
+    public GcInfo getGcInfo() {
+        return gcInfo;
+    }
+
+    /**
+     * Returns a {@code GarbageCollectionNotificationInfo} object represented by the
+     * given {@code CompositeData}.
+     * The given {@code CompositeData} must contain
+     * the following attributes:
+     * <blockquote>
+     * <table border>
+     * <tr>
+     *   <th align=left>Attribute Name</th>
+     *   <th align=left>Type</th>
+     * </tr>
+     * <tr>
+     *   <td>gcName</td>
+     *   <td>{@code java.lang.String}</td>
+     * </tr>
+     * <tr>
+     *   <td>gcAction</td>
+     *   <td>{@code java.lang.String}</td>
+     * </tr>
+     * <tr>
+     *   <td>gcCause</td>
+     *   <td>{@code java.lang.String}</td>
+     * </tr>
+     * <tr>
+     *   <td>gcInfo</td>
+     *   <td>{@code javax.management.openmbean.CompositeData}</td>
+     * </tr>
+     * </table>
+     * </blockquote>
+     *
+     * @param cd {@code CompositeData} representing a
+     *           {@code GarbageCollectionNotificationInfo}
+     *
+     * @throws IllegalArgumentException if {@code cd} does not
+     *   represent a {@code GarbaageCollectionNotificationInfo} object.
+     *
+     * @return a {@code GarbageCollectionNotificationInfo} object represented
+     *         by {@code cd} if {@code cd} is not {@code null};
+     *         {@code null} otherwise.
+     */
+    public static GarbageCollectionNotificationInfo from(CompositeData cd) {
+        if (cd == null) {
+            return null;
+        }
+
+        if (cd instanceof GarbageCollectionNotifInfoCompositeData) {
+            return ((GarbageCollectionNotifInfoCompositeData) cd).getGarbageCollectionNotifInfo();
+        } else {
+            return new GarbageCollectionNotificationInfo(cd);
+        }
+    }
+
+    public CompositeData toCompositeData(CompositeType ct) {
+        return cdata;
+    }
+
+}
--- a/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java	Wed May 18 13:19:32 2011 +0200
@@ -179,7 +179,7 @@
      * completely received. For messages being sent {@code true} indicates that
      * the message is complete, {@code false} indicates that the message is not
      * complete. How the send channel interprets this value depends on the value
-     * of its {@link SctpStandardSocketOption#SCTP_EXPLICIT_COMPLETE
+     * of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
      * SCTP_EXPLICIT_COMPLETE} socket option.
      *
      * @return  {@code true} if, and only if, the message is complete
@@ -192,7 +192,7 @@
      * <P> For messages being sent {@code true} indicates that
      * the message is complete, {@code false} indicates that the message is not
      * complete. How the send channel interprets this value depends on the value
-     * of its {@link SctpStandardSocketOption#SCTP_EXPLICIT_COMPLETE
+     * of its {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
      * SCTP_EXPLICIT_COMPLETE} socket option.
      *
      * @param  complete
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -65,55 +65,55 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_DISABLE_FRAGMENTS
+ *     <td> {@link SctpStandardSocketOptions#SCTP_DISABLE_FRAGMENTS
  *                                          SCTP_DISABLE_FRAGMENTS} </td>
  *     <td> Enables or disables message fragmentation </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_EXPLICIT_COMPLETE
+ *     <td> {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
  *                                          SCTP_EXPLICIT_COMPLETE} </td>
  *     <td> Enables or disables explicit message completion </td>
  *   </tr>
  *    <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_FRAGMENT_INTERLEAVE
+ *     <td> {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
  *                                          SCTP_FRAGMENT_INTERLEAVE} </td>
  *     <td> Controls how the presentation of messages occur for the message
  *          receiver </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_INIT_MAXSTREAMS
+ *     <td> {@link SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS
  *                                          SCTP_INIT_MAXSTREAMS} </td>
  *     <td> The maximum number of streams requested by the local endpoint during
  *          association initialization </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_NODELAY SCTP_NODELAY} </td>
+ *     <td> {@link SctpStandardSocketOptions#SCTP_NODELAY SCTP_NODELAY} </td>
  *     <td> Enables or disable a Nagle-like algorithm </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_PRIMARY_ADDR
+ *     <td> {@link SctpStandardSocketOptions#SCTP_PRIMARY_ADDR
  *                                          SCTP_PRIMARY_ADDR} </td>
  *     <td> Requests that the local SCTP stack use the given peer address as the
  *          association primary </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_SET_PEER_PRIMARY_ADDR
+ *     <td> {@link SctpStandardSocketOptions#SCTP_SET_PEER_PRIMARY_ADDR
  *                                          SCTP_SET_PEER_PRIMARY_ADDR} </td>
  *     <td> Requests that the peer mark the enclosed address as the association
  *          primary </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SO_SNDBUF
+ *     <td> {@link SctpStandardSocketOptions#SO_SNDBUF
  *                                          SO_SNDBUF} </td>
  *     <td> The size of the socket send buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SO_RCVBUF
+ *     <td> {@link SctpStandardSocketOptions#SO_RCVBUF
  *                                          SO_RCVBUF} </td>
  *     <td> The size of the socket receive buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SO_LINGER
+ *     <td> {@link SctpStandardSocketOptions#SO_LINGER
  *                                          SO_LINGER} </td>
  *     <td> Linger on close if data is present (when configured in blocking mode
  *          only) </td>
@@ -449,7 +449,7 @@
      * <P> This is a convience method and is equivalent to evaluating the
      * following expression:
      * <blockquote><pre>
-     * setOption(SctpStandardSocketOption.SCTP_INIT_MAXSTREAMS, SctpStandardSocketOption.InitMaxStreams.create(maxInStreams, maxOutStreams))
+     * setOption(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS, SctpStandardSocketOption.InitMaxStreams.create(maxInStreams, maxOutStreams))
      *  .connect(remote);
      * </pre></blockquote>
      *
@@ -651,7 +651,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see SctpStandardSocketOption
+     * @see SctpStandardSocketOptions
      */
     public abstract <T> T getOption(SctpSocketOption<T> name)
         throws IOException;
@@ -680,7 +680,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see SctpStandardSocketOption
+     * @see SctpStandardSocketOptions
      */
     public abstract <T> SctpChannel setOption(SctpSocketOption<T> name, T value)
         throws IOException;
@@ -731,7 +731,7 @@
      * MessageInfo} will return {@code false}, and more invocations of this
      * method will be necessary to completely consume the messgae. Only
      * one message at a time will be partially delivered in any stream. The
-     * socket option {@link SctpStandardSocketOption#SCTP_FRAGMENT_INTERLEAVE
+     * socket option {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
      * SCTP_FRAGMENT_INTERLEAVE} controls various aspects of what interlacing of
      * messages occurs.
      *
@@ -804,7 +804,7 @@
      * and sufficient room becomes available, then the remaining bytes in the
      * given byte buffer are transmitted as a single message. Sending a message
      * is atomic unless explicit message completion {@link
-     * SctpStandardSocketOption#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}
+     * SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}
      * socket option is enabled on this channel's socket.
      *
      * <P> The message is transferred from the byte buffer as if by a regular
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -69,55 +69,55 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_DISABLE_FRAGMENTS
+ *     <td> {@link SctpStandardSocketOptions#SCTP_DISABLE_FRAGMENTS
  *                                          SCTP_DISABLE_FRAGMENTS} </td>
  *     <td> Enables or disables message fragmentation </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_EXPLICIT_COMPLETE
+ *     <td> {@link SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE
  *                                          SCTP_EXPLICIT_COMPLETE} </td>
  *     <td> Enables or disables explicit message completion </td>
  *   </tr>
  *    <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_FRAGMENT_INTERLEAVE
+ *     <td> {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
  *                                          SCTP_FRAGMENT_INTERLEAVE} </td>
  *     <td> Controls how the presentation of messages occur for the message
  *          receiver </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_INIT_MAXSTREAMS
+ *     <td> {@link SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS
  *                                          SCTP_INIT_MAXSTREAMS} </td>
  *     <td> The maximum number of streams requested by the local endpoint during
  *          association initialization </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_NODELAY SCTP_NODELAY} </td>
+ *     <td> {@link SctpStandardSocketOptions#SCTP_NODELAY SCTP_NODELAY} </td>
  *     <td> Enables or disable a Nagle-like algorithm </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_PRIMARY_ADDR
+ *     <td> {@link SctpStandardSocketOptions#SCTP_PRIMARY_ADDR
  *                                          SCTP_PRIMARY_ADDR} </td>
  *     <td> Requests that the local SCTP stack use the given peer address as the
  *          association primary </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_SET_PEER_PRIMARY_ADDR
+ *     <td> {@link SctpStandardSocketOptions#SCTP_SET_PEER_PRIMARY_ADDR
  *                                          SCTP_SET_PEER_PRIMARY_ADDR} </td>
  *     <td> Requests that the peer mark the enclosed address as the association
  *          primary </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SO_SNDBUF
+ *     <td> {@link SctpStandardSocketOptions#SO_SNDBUF
  *                                          SO_SNDBUF} </td>
  *     <td> The size of the socket send buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SO_RCVBUF
+ *     <td> {@link SctpStandardSocketOptions#SO_RCVBUF
  *                                          SO_RCVBUF} </td>
  *     <td> The size of the socket receive buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SO_LINGER
+ *     <td> {@link SctpStandardSocketOptions#SO_LINGER
  *                                          SO_LINGER} </td>
  *     <td> Linger on close if data is present (when configured in blocking mode
  *          only) </td>
@@ -450,7 +450,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see SctpStandardSocketOption
+     * @see SctpStandardSocketOptions
      */
     public abstract <T> T getOption(SctpSocketOption<T> name,
                                     Association association)
@@ -489,7 +489,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see SctpStandardSocketOption
+     * @see SctpStandardSocketOptions
      */
     public abstract <T> SctpMultiChannel setOption(SctpSocketOption<T> name,
                                                    T value,
@@ -542,7 +542,7 @@
      * MessageInfo} will return {@code false}, and more invocations of this
      * method will be necessary to completely consume the messgae. Only
      * one message at a time will be partially delivered in any stream. The
-     * socket option {@link SctpStandardSocketOption#SCTP_FRAGMENT_INTERLEAVE
+     * socket option {@link SctpStandardSocketOptions#SCTP_FRAGMENT_INTERLEAVE
      * SCTP_FRAGMENT_INTERLEAVE} controls various aspects of what interlacing of
      * messages occurs.
      *
@@ -635,14 +635,14 @@
      * underlying output buffer, then the remaining bytes in the given byte
      * buffer are transmitted as a single message. Sending a message
      * is atomic unless explicit message completion {@link
-     * SctpStandardSocketOption#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}
+     * SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}
      * socket option is enabled on this channel's socket.
      *
      * <P> If this channel is in non-blocking mode, there is sufficient room
      * in the underlying output buffer, and an implicit association setup is
      * required, then the remaining bytes in the given byte buffer are
      * transmitted as a single message, subject to {@link
-     * SctpStandardSocketOption#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}.
+     * SctpStandardSocketOptions#SCTP_EXPLICIT_COMPLETE SCTP_EXPLICIT_COMPLETE}.
      * If for any reason the message cannot
      * be delivered an {@link AssociationChangeNotification association
      * changed} notification is put on the SCTP stack with its {@code event} parameter set
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -53,7 +53,7 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link SctpStandardSocketOption#SCTP_INIT_MAXSTREAMS
+ *     <td> {@link SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS
  *                                          SCTP_INIT_MAXSTREAMS} </td>
  *     <td> The maximum number of streams requested by the local endpoint during
  *          association initialization </td>
@@ -360,7 +360,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see SctpStandardSocketOption
+     * @see SctpStandardSocketOptions
      */
     public abstract <T> T getOption(SctpSocketOption<T> name) throws IOException;
 
@@ -388,7 +388,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see SctpStandardSocketOption
+     * @see SctpStandardSocketOptions
      */
     public abstract <T> SctpServerChannel setOption(SctpSocketOption<T> name,
                                                     T value)
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpSocketOption.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpSocketOption.java	Wed May 18 13:19:32 2011 +0200
@@ -33,6 +33,6 @@
  *
  * @since 1.7
  *
- * @see SctpStandardSocketOption
+ * @see SctpStandardSocketOptions
  */
 public interface SctpSocketOption<T> extends SocketOption<T> { }
--- a/jdk/src/share/classes/com/sun/nio/sctp/SctpStandardSocketOption.java	Tue May 17 00:56:01 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,419 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.nio.sctp;
-
-import java.net.SocketAddress;
-import sun.nio.ch.SctpStdSocketOption;
-
-/**
- * SCTP channels supports the socket options defined by this class
- * (as well as those listed in the particular channel class) and may support
- * additional Implementation specific socket options.
- *
- * @since 1.7
- */
-public class SctpStandardSocketOption {
-    private SctpStandardSocketOption() {}
-    /**
-     * Enables or disables message fragmentation.
-     *
-     * <P> The value of this socket option is a {@code Boolean} that represents
-     * whether the option is enabled or disabled. If enabled no SCTP message
-     * fragmentation will be performed. Instead if a message being sent
-     * exceeds the current PMTU size, the message will NOT be sent and
-     * an error will be indicated to the user.
-     *
-     * <P> It is implementation specific whether or not this option is
-     * supported.
-     */
-    public static final SctpSocketOption<Boolean> SCTP_DISABLE_FRAGMENTS = new
-        SctpStdSocketOption<Boolean>("SCTP_DISABLE_FRAGMENTS", Boolean.class,
-        sun.nio.ch.SctpStdSocketOption.SCTP_DISABLE_FRAGMENTS);
-
-    /**
-     * Enables or disables explicit message completion.
-     *
-     * <p> The value of this socket option is a {@code Boolean} that represents
-     * whether the option is enabled or disabled. When this option is enabled,
-     * the {@code send} method may be invoked multiple times to a send message.
-     * The {@code isComplete} parameter of the {@link MessageInfo} must only
-     * be set to {@code true} for the final send to indicate that the message is
-     * complete. If this option is disabled then each individual {@code send}
-     * invocation is considered complete.
-     *
-     * <P> The default value of the option is {@code false} indicating that the
-     * option is disabled. It is implementation specific whether or not this
-     * option is supported.
-     */
-    public static final SctpSocketOption<Boolean> SCTP_EXPLICIT_COMPLETE = new
-        SctpStdSocketOption<Boolean>("SCTP_EXPLICIT_COMPLETE", Boolean.class,
-        sun.nio.ch.SctpStdSocketOption.SCTP_EXPLICIT_COMPLETE);
-
-    /**
-     * Fragmented interleave controls how the presentation of messages occur
-     * for the message receiver. There are three levels of fragment interleave
-     * defined. Two of the levels effect {@link SctpChannel}, while
-     * {@link SctpMultiChannel} is effected by all three levels.
-     *
-     * <P> This option takes an {@code Integer} value. It can be set to a value
-     * of {@code 0}, {@code 1} or {@code 2}.
-     *
-     * <P> Setting the three levels provides the following receiver
-     * interactions:
-     *
-     * <P> {@code level 0} - Prevents the interleaving of any messages. This
-     * means that when a partial delivery begins, no other messages will be
-     * received except the message being partially delivered. If another message
-     * arrives on a different stream (or association) that could be delivered,
-     * it will be blocked waiting for the user to read all of the partially
-     * delivered message.
-     *
-     * <P> {@code level 1} - Allows interleaving of messages that are from
-     * different associations. For {@code SctpChannel}, level 0 and
-     * level 1 have the same meaning since an {@code SctpChannel} always
-     * receives messages from the same association. Note that setting an {@code
-     * SctpMultiChannel} to this level may cause multiple partial
-     * delivers from different associations but for any given association, only
-     * one message will be delivered until all parts of a message have been
-     * delivered. This means that one large message, being read with an
-     * association identification of "X", will block other messages from
-     * association "X" from being delivered.
-     *
-     * <P> {@code level 2} - Allows complete interleaving of messages. This
-     * level requires that the sender carefully observe not only the peer
-     * {@code Association} but also must pay careful attention to the stream
-     * number. With this option enabled a partially delivered message may begin
-     * being delivered for association "X" stream "Y" and the next subsequent
-     * receive may return a message from association "X" stream "Z". Note that
-     * no other messages would be delivered for association "X" stream "Y"
-     * until all of stream "Y"'s partially delivered message was read.
-     * Note that this option effects both channel types.  Also note that
-     * for an {@code SctpMultiChannel} not only may another streams
-     * message from the same association be delivered from the next receive,
-     * some other associations message may be delivered upon the next receive.
-     *
-     * <P> It is implementation specific whether or not this option is
-     * supported.
-     */
-    public static final SctpSocketOption<Integer> SCTP_FRAGMENT_INTERLEAVE =
-            new SctpStdSocketOption<Integer>("SCTP_FRAGMENT_INTERLEAVE",
-                  Integer.class,
-                  sun.nio.ch.SctpStdSocketOption.SCTP_FRAGMENT_INTERLEAVE);
-
-    /**
-     * The maximum number of streams requested by the local endpoint during
-     * association initialization.
-     *
-     * <P> The value of this socket option is an {@link
-     * SctpStandardSocketOption.InitMaxStreams InitMaxStreams}, that represents
-     * the maximum number of inbound and outbound streams that an association
-     * on the channel is prepared to support.
-     *
-     * <P> For an {@link SctpChannel} this option may only be used to
-     * change the number of inbound/outbound streams prior to connecting.
-     *
-     * <P> For an {@link SctpMultiChannel} this option determines
-     * the maximum number of inbound/outbound streams new associations setup
-     * on the channel will be prepared to support.
-     *
-     * <P> For an {@link SctpServerChannel} this option determines the
-     * maximum number of inbound/outbound streams accepted sockets will
-     * negotiate with their connecting peer.
-     *
-     * <P> In all cases the value set by this option is used in the negotiation
-     * of new associations setup on the channel's socket and the actual
-     * maximum number of inbound/outbound streams that have been negotiated
-     * with the peer can be retrieved from the appropriate {@link
-     * Association}. The {@code Association} can be retrieved from the
-     * {@link AssociationChangeNotification.AssocChangeEvent#COMM_UP COMM_UP}
-     * {@link AssociationChangeNotification} belonging to that association.
-     *
-     * <p> This value is bounded by the actual implementation. In other
-     * words the user may be able to support more streams than the Operating
-     * System. In such a case, the Operating System limit may override the
-     * value requested by the user. The default value of 0 indicates to use
-     * the endpoints default value.
-     */
-    public static final SctpSocketOption
-        <SctpStandardSocketOption.InitMaxStreams> SCTP_INIT_MAXSTREAMS =
-        new SctpStdSocketOption<SctpStandardSocketOption.InitMaxStreams>(
-        "SCTP_INIT_MAXSTREAMS", SctpStandardSocketOption.InitMaxStreams.class);
-
-    /**
-     * Enables or disables a Nagle-like algorithm.
-     *
-     * <P> The value of this socket option is a {@code Boolean} that represents
-     * whether the option is enabled or disabled. SCTP uses an algorithm like
-     * <em>The Nagle Algorithm</em> to coalesce short segments and
-     * improve network efficiency.
-     */
-    public static final SctpSocketOption<Boolean> SCTP_NODELAY =
-        new SctpStdSocketOption<Boolean>("SCTP_NODELAY", Boolean.class,
-        sun.nio.ch.SctpStdSocketOption.SCTP_NODELAY);
-
-    /**
-     * Requests that the local SCTP stack use the given peer address as
-     * the association primary.
-     *
-     * <P> The value of this socket option is a {@code SocketAddress}
-     * that represents the peer address that the local SCTP stack should use as
-     * the association primary. The address must be one of the association
-     * peer's addresses.
-     *
-     * <P> An {@code SctpMultiChannel} can control more than one
-     * association, the association parameter must be given when setting or
-     * retrieving this option.
-     *
-     * <P> Since {@code SctpChannel} only controls one association,
-     * the association parameter is not required and this option can be
-     * set or queried directly.
-     */
-     public static final SctpSocketOption<SocketAddress> SCTP_PRIMARY_ADDR =
-             new SctpStdSocketOption<SocketAddress>
-             ("SCTP_PRIMARY_ADDR", SocketAddress.class);
-
-     /**
-     * Requests that the peer mark the enclosed address as the association
-     * primary.
-     *
-     * <P> The value of this socket option is a {@code SocketAddress}
-     * that represents the local address that the peer should use as its
-     * primary address. The given address must be one of the association's
-     * locally bound addresses.
-     *
-     * <P> An {@code SctpMultiChannel} can control more than one
-     * association, the association parameter must be given when setting or
-     * retrieving this option.
-     *
-     * <P> Since {@code SctpChannel} only controls one association,
-     * the association parameter is not required and this option can be
-     * queried directly.
-     *
-     * <P> Note, this is a set only option and cannot be retrieved by {@code
-     * getOption}. It is implementation specific whether or not this
-     * option is supported.
-     */
-    public static final SctpSocketOption<SocketAddress> SCTP_SET_PEER_PRIMARY_ADDR =
-            new SctpStdSocketOption<SocketAddress>
-            ("SCTP_SET_PEER_PRIMARY_ADDR", SocketAddress.class);
-
-    /**
-     * The size of the socket send buffer.
-     *
-     * <p> The value of this socket option is an {@code Integer} that is the
-     * size of the socket send buffer in bytes. The socket send buffer is an
-     * output buffer used by the networking implementation. It may need to be
-     * increased for high-volume connections. The value of the socket option is
-     * a <em>hint</em> to the implementation to size the buffer and the actual
-     * size may differ. The socket option can be queried to retrieve the actual
-     * size.
-     *
-     * <p> For {@code SctpChannel}, this controls the amount of data
-     * the SCTP stack may have waiting in internal buffers to be sent. This
-     * option therefore bounds the maximum size of data that can be sent in a
-     * single send call.
-     *
-     * <P> For {@code SctpMultiChannel}, the effect is the same as for {@code
-     * SctpChannel}, except that it applies to all associations. The option
-     * applies to each association's window size separately.
-     *
-     * <p> An implementation allows this socket option to be set before the
-     * socket is bound or connected. Whether an implementation allows the
-     * socket send buffer to be changed after the socket is bound is system
-     * dependent.
-     */
-    public static final SctpSocketOption<Integer> SO_SNDBUF =
-        new SctpStdSocketOption<Integer>("SO_SNDBUF", Integer.class,
-        sun.nio.ch.SctpStdSocketOption.SO_SNDBUF);
-
-    /**
-     * The size of the socket receive buffer.
-     *
-     * <P> The value of this socket option is an {@code Integer} that is the
-     * size of the socket receive buffer in bytes. The socket receive buffer is
-     * an input buffer used by the networking implementation. It may need to be
-     * increased for high-volume connections or decreased to limit the possible
-     * backlog of incoming data. The value of the socket option is a
-     * <em>hint</em> to the implementation to size the buffer and the actual
-     * size may differ.
-     *
-     * <P> For {@code SctpChannel}, this controls the receiver window size.
-     *
-     * <P> For {@code SctpMultiChannel}, the meaning is implementation
-     * dependent. It might control the receive buffer for each association bound
-     * to the socket descriptor or it might control the receive buffer for the
-     * whole socket.
-     *
-     * <p> An implementation allows this socket option to be set before the
-     * socket is bound or connected. Whether an implementation allows the
-     * socket receive buffer to be changed after the socket is bound is system
-     * dependent.
-     */
-    public static final SctpSocketOption<Integer> SO_RCVBUF =
-        new SctpStdSocketOption<Integer>("SO_RCVBUF", Integer.class,
-        sun.nio.ch.SctpStdSocketOption.SO_RCVBUF);
-
-    /**
-     * Linger on close if data is present.
-     *
-     * <p> The value of this socket option is an {@code Integer} that controls
-     * the action taken when unsent data is queued on the socket and a method
-     * to close the socket is invoked. If the value of the socket option is zero
-     * or greater, then it represents a timeout value, in seconds, known as the
-     * <em>linger interval</em>. The linger interval is the timeout for the
-     * {@code close} method to block while the operating system attempts to
-     * transmit the unsent data or it decides that it is unable to transmit the
-     * data. If the value of the socket option is less than zero then the option
-     * is disabled. In that case the {@code close} method does not wait until
-     * unsent data is transmitted; if possible the operating system will transmit
-     * any unsent data before the connection is closed.
-     *
-     * <p> This socket option is intended for use with sockets that are configured
-     * in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
-     * only. The behavior of the {@code close} method when this option is
-     * enabled on a non-blocking socket is not defined.
-     *
-     * <p> The initial value of this socket option is a negative value, meaning
-     * that the option is disabled. The option may be enabled, or the linger
-     * interval changed, at any time. The maximum value of the linger interval
-     * is system dependent. Setting the linger interval to a value that is
-     * greater than its maximum value causes the linger interval to be set to
-     * its maximum value.
-     */
-    public static final SctpSocketOption<Integer> SO_LINGER =
-        new SctpStdSocketOption<Integer>("SO_LINGER", Integer.class,
-        sun.nio.ch.SctpStdSocketOption.SO_LINGER);
-
-    /**
-     * This class is used to set the maximum number of inbound/outbound streams
-     * used by the local endpoint during association initialization. An
-     * instance of this class is used to set the {@link
-     * SctpStandardSocketOption#SCTP_INIT_MAXSTREAMS SCTP_INIT_MAXSTREAMS}
-     * socket option.
-     *
-     * @since 1.7
-     */
-    public static class InitMaxStreams {
-        private int maxInStreams;
-        private int maxOutStreams;
-
-        private InitMaxStreams(int maxInStreams, int maxOutStreams) {
-           this.maxInStreams = maxInStreams;
-           this.maxOutStreams = maxOutStreams;
-        }
-
-        /**
-         * Creates an InitMaxStreams instance.
-         *
-         * @param  maxInStreams
-         *         The maximum number of inbound streams, where
-         *         {@code 0 <= maxInStreams <= 65536}
-         *
-         * @param  maxOutStreams
-         *         The maximum number of outbound streams, where
-         *         {@code 0 <= maxOutStreams <= 65536}
-         *
-         * @return  An {@code InitMaxStreams} instance
-         *
-         * @throws  IllegalArgumentException
-         *          If an argument is outside of specified bounds
-         */
-        public static InitMaxStreams create
-              (int maxInStreams, int maxOutStreams) {
-            if (maxOutStreams < 0 || maxOutStreams > 65535)
-                throw new IllegalArgumentException(
-                      "Invalid maxOutStreams value");
-            if (maxInStreams < 0 || maxInStreams > 65535)
-                throw new IllegalArgumentException(
-                      "Invalid maxInStreams value");
-
-            return new InitMaxStreams(maxInStreams, maxOutStreams);
-        }
-
-        /**
-         * Returns the maximum number of inbound streams.
-         *
-         * @return  Maximum inbound streams
-         */
-        public int maxInStreams() {
-            return maxInStreams;
-        }
-
-        /**
-         * Returns the maximum number of outbound streams.
-         *
-         * @return  Maximum outbound streams
-         */
-        public int maxOutStreams() {
-            return maxOutStreams;
-        }
-
-        /**
-         * Returns a string representation of this init max streams, including
-         * the maximum in and out bound streams.
-         *
-         * @return  A string representation of this init max streams
-         */
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append(super.toString()).append(" [");
-            sb.append("maxInStreams:").append(maxInStreams);
-            sb.append("maxOutStreams:").append(maxOutStreams).append("]");
-            return sb.toString();
-        }
-
-        /**
-         * Returns true if the specified object is another {@code InitMaxStreams}
-         * instance with the same number of in and out bound streams.
-         *
-         * @param  obj
-         *         The object to be compared with this init max streams
-         *
-         * @return  true if the specified object is another
-         *          {@code InitMaxStreams} instance with the same number of in
-         *          and out bound streams
-         */
-        @Override
-        public boolean equals(Object obj) {
-            if (obj != null && obj instanceof InitMaxStreams) {
-                InitMaxStreams that = (InitMaxStreams) obj;
-                if (this.maxInStreams == that.maxInStreams &&
-                    this.maxOutStreams == that.maxOutStreams)
-                    return true;
-            }
-            return false;
-        }
-
-        /**
-         * Returns a hash code value for this init max streams.
-         */
-        @Override
-        public int hashCode() {
-            int hash = 7 ^ maxInStreams ^ maxOutStreams;
-            return hash;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpStandardSocketOptions.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.nio.sctp;
+
+import java.net.SocketAddress;
+import sun.nio.ch.SctpStdSocketOption;
+
+/**
+ * SCTP channels supports the socket options defined by this class
+ * (as well as those listed in the particular channel class) and may support
+ * additional Implementation specific socket options.
+ *
+ * @since 1.7
+ */
+public class SctpStandardSocketOptions {
+    private SctpStandardSocketOptions() {}
+    /**
+     * Enables or disables message fragmentation.
+     *
+     * <P> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. If enabled no SCTP message
+     * fragmentation will be performed. Instead if a message being sent
+     * exceeds the current PMTU size, the message will NOT be sent and
+     * an error will be indicated to the user.
+     *
+     * <P> It is implementation specific whether or not this option is
+     * supported.
+     */
+    public static final SctpSocketOption<Boolean> SCTP_DISABLE_FRAGMENTS = new
+        SctpStdSocketOption<Boolean>("SCTP_DISABLE_FRAGMENTS", Boolean.class,
+        sun.nio.ch.SctpStdSocketOption.SCTP_DISABLE_FRAGMENTS);
+
+    /**
+     * Enables or disables explicit message completion.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. When this option is enabled,
+     * the {@code send} method may be invoked multiple times to a send message.
+     * The {@code isComplete} parameter of the {@link MessageInfo} must only
+     * be set to {@code true} for the final send to indicate that the message is
+     * complete. If this option is disabled then each individual {@code send}
+     * invocation is considered complete.
+     *
+     * <P> The default value of the option is {@code false} indicating that the
+     * option is disabled. It is implementation specific whether or not this
+     * option is supported.
+     */
+    public static final SctpSocketOption<Boolean> SCTP_EXPLICIT_COMPLETE = new
+        SctpStdSocketOption<Boolean>("SCTP_EXPLICIT_COMPLETE", Boolean.class,
+        sun.nio.ch.SctpStdSocketOption.SCTP_EXPLICIT_COMPLETE);
+
+    /**
+     * Fragmented interleave controls how the presentation of messages occur
+     * for the message receiver. There are three levels of fragment interleave
+     * defined. Two of the levels effect {@link SctpChannel}, while
+     * {@link SctpMultiChannel} is effected by all three levels.
+     *
+     * <P> This option takes an {@code Integer} value. It can be set to a value
+     * of {@code 0}, {@code 1} or {@code 2}.
+     *
+     * <P> Setting the three levels provides the following receiver
+     * interactions:
+     *
+     * <P> {@code level 0} - Prevents the interleaving of any messages. This
+     * means that when a partial delivery begins, no other messages will be
+     * received except the message being partially delivered. If another message
+     * arrives on a different stream (or association) that could be delivered,
+     * it will be blocked waiting for the user to read all of the partially
+     * delivered message.
+     *
+     * <P> {@code level 1} - Allows interleaving of messages that are from
+     * different associations. For {@code SctpChannel}, level 0 and
+     * level 1 have the same meaning since an {@code SctpChannel} always
+     * receives messages from the same association. Note that setting an {@code
+     * SctpMultiChannel} to this level may cause multiple partial
+     * delivers from different associations but for any given association, only
+     * one message will be delivered until all parts of a message have been
+     * delivered. This means that one large message, being read with an
+     * association identification of "X", will block other messages from
+     * association "X" from being delivered.
+     *
+     * <P> {@code level 2} - Allows complete interleaving of messages. This
+     * level requires that the sender carefully observe not only the peer
+     * {@code Association} but also must pay careful attention to the stream
+     * number. With this option enabled a partially delivered message may begin
+     * being delivered for association "X" stream "Y" and the next subsequent
+     * receive may return a message from association "X" stream "Z". Note that
+     * no other messages would be delivered for association "X" stream "Y"
+     * until all of stream "Y"'s partially delivered message was read.
+     * Note that this option effects both channel types.  Also note that
+     * for an {@code SctpMultiChannel} not only may another streams
+     * message from the same association be delivered from the next receive,
+     * some other associations message may be delivered upon the next receive.
+     *
+     * <P> It is implementation specific whether or not this option is
+     * supported.
+     */
+    public static final SctpSocketOption<Integer> SCTP_FRAGMENT_INTERLEAVE =
+            new SctpStdSocketOption<Integer>("SCTP_FRAGMENT_INTERLEAVE",
+                  Integer.class,
+                  sun.nio.ch.SctpStdSocketOption.SCTP_FRAGMENT_INTERLEAVE);
+
+    /**
+     * The maximum number of streams requested by the local endpoint during
+     * association initialization.
+     *
+     * <P> The value of this socket option is an {@link
+     * SctpStandardSocketOptions.InitMaxStreams InitMaxStreams}, that represents
+     * the maximum number of inbound and outbound streams that an association
+     * on the channel is prepared to support.
+     *
+     * <P> For an {@link SctpChannel} this option may only be used to
+     * change the number of inbound/outbound streams prior to connecting.
+     *
+     * <P> For an {@link SctpMultiChannel} this option determines
+     * the maximum number of inbound/outbound streams new associations setup
+     * on the channel will be prepared to support.
+     *
+     * <P> For an {@link SctpServerChannel} this option determines the
+     * maximum number of inbound/outbound streams accepted sockets will
+     * negotiate with their connecting peer.
+     *
+     * <P> In all cases the value set by this option is used in the negotiation
+     * of new associations setup on the channel's socket and the actual
+     * maximum number of inbound/outbound streams that have been negotiated
+     * with the peer can be retrieved from the appropriate {@link
+     * Association}. The {@code Association} can be retrieved from the
+     * {@link AssociationChangeNotification.AssocChangeEvent#COMM_UP COMM_UP}
+     * {@link AssociationChangeNotification} belonging to that association.
+     *
+     * <p> This value is bounded by the actual implementation. In other
+     * words the user may be able to support more streams than the Operating
+     * System. In such a case, the Operating System limit may override the
+     * value requested by the user. The default value of 0 indicates to use
+     * the endpoints default value.
+     */
+    public static final SctpSocketOption
+        <SctpStandardSocketOptions.InitMaxStreams> SCTP_INIT_MAXSTREAMS =
+        new SctpStdSocketOption<SctpStandardSocketOptions.InitMaxStreams>(
+        "SCTP_INIT_MAXSTREAMS", SctpStandardSocketOptions.InitMaxStreams.class);
+
+    /**
+     * Enables or disables a Nagle-like algorithm.
+     *
+     * <P> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. SCTP uses an algorithm like
+     * <em>The Nagle Algorithm</em> to coalesce short segments and
+     * improve network efficiency.
+     */
+    public static final SctpSocketOption<Boolean> SCTP_NODELAY =
+        new SctpStdSocketOption<Boolean>("SCTP_NODELAY", Boolean.class,
+        sun.nio.ch.SctpStdSocketOption.SCTP_NODELAY);
+
+    /**
+     * Requests that the local SCTP stack use the given peer address as
+     * the association primary.
+     *
+     * <P> The value of this socket option is a {@code SocketAddress}
+     * that represents the peer address that the local SCTP stack should use as
+     * the association primary. The address must be one of the association
+     * peer's addresses.
+     *
+     * <P> An {@code SctpMultiChannel} can control more than one
+     * association, the association parameter must be given when setting or
+     * retrieving this option.
+     *
+     * <P> Since {@code SctpChannel} only controls one association,
+     * the association parameter is not required and this option can be
+     * set or queried directly.
+     */
+     public static final SctpSocketOption<SocketAddress> SCTP_PRIMARY_ADDR =
+             new SctpStdSocketOption<SocketAddress>
+             ("SCTP_PRIMARY_ADDR", SocketAddress.class);
+
+     /**
+     * Requests that the peer mark the enclosed address as the association
+     * primary.
+     *
+     * <P> The value of this socket option is a {@code SocketAddress}
+     * that represents the local address that the peer should use as its
+     * primary address. The given address must be one of the association's
+     * locally bound addresses.
+     *
+     * <P> An {@code SctpMultiChannel} can control more than one
+     * association, the association parameter must be given when setting or
+     * retrieving this option.
+     *
+     * <P> Since {@code SctpChannel} only controls one association,
+     * the association parameter is not required and this option can be
+     * queried directly.
+     *
+     * <P> Note, this is a set only option and cannot be retrieved by {@code
+     * getOption}. It is implementation specific whether or not this
+     * option is supported.
+     */
+    public static final SctpSocketOption<SocketAddress> SCTP_SET_PEER_PRIMARY_ADDR =
+            new SctpStdSocketOption<SocketAddress>
+            ("SCTP_SET_PEER_PRIMARY_ADDR", SocketAddress.class);
+
+    /**
+     * The size of the socket send buffer.
+     *
+     * <p> The value of this socket option is an {@code Integer} that is the
+     * size of the socket send buffer in bytes. The socket send buffer is an
+     * output buffer used by the networking implementation. It may need to be
+     * increased for high-volume connections. The value of the socket option is
+     * a <em>hint</em> to the implementation to size the buffer and the actual
+     * size may differ. The socket option can be queried to retrieve the actual
+     * size.
+     *
+     * <p> For {@code SctpChannel}, this controls the amount of data
+     * the SCTP stack may have waiting in internal buffers to be sent. This
+     * option therefore bounds the maximum size of data that can be sent in a
+     * single send call.
+     *
+     * <P> For {@code SctpMultiChannel}, the effect is the same as for {@code
+     * SctpChannel}, except that it applies to all associations. The option
+     * applies to each association's window size separately.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Whether an implementation allows the
+     * socket send buffer to be changed after the socket is bound is system
+     * dependent.
+     */
+    public static final SctpSocketOption<Integer> SO_SNDBUF =
+        new SctpStdSocketOption<Integer>("SO_SNDBUF", Integer.class,
+        sun.nio.ch.SctpStdSocketOption.SO_SNDBUF);
+
+    /**
+     * The size of the socket receive buffer.
+     *
+     * <P> The value of this socket option is an {@code Integer} that is the
+     * size of the socket receive buffer in bytes. The socket receive buffer is
+     * an input buffer used by the networking implementation. It may need to be
+     * increased for high-volume connections or decreased to limit the possible
+     * backlog of incoming data. The value of the socket option is a
+     * <em>hint</em> to the implementation to size the buffer and the actual
+     * size may differ.
+     *
+     * <P> For {@code SctpChannel}, this controls the receiver window size.
+     *
+     * <P> For {@code SctpMultiChannel}, the meaning is implementation
+     * dependent. It might control the receive buffer for each association bound
+     * to the socket descriptor or it might control the receive buffer for the
+     * whole socket.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Whether an implementation allows the
+     * socket receive buffer to be changed after the socket is bound is system
+     * dependent.
+     */
+    public static final SctpSocketOption<Integer> SO_RCVBUF =
+        new SctpStdSocketOption<Integer>("SO_RCVBUF", Integer.class,
+        sun.nio.ch.SctpStdSocketOption.SO_RCVBUF);
+
+    /**
+     * Linger on close if data is present.
+     *
+     * <p> The value of this socket option is an {@code Integer} that controls
+     * the action taken when unsent data is queued on the socket and a method
+     * to close the socket is invoked. If the value of the socket option is zero
+     * or greater, then it represents a timeout value, in seconds, known as the
+     * <em>linger interval</em>. The linger interval is the timeout for the
+     * {@code close} method to block while the operating system attempts to
+     * transmit the unsent data or it decides that it is unable to transmit the
+     * data. If the value of the socket option is less than zero then the option
+     * is disabled. In that case the {@code close} method does not wait until
+     * unsent data is transmitted; if possible the operating system will transmit
+     * any unsent data before the connection is closed.
+     *
+     * <p> This socket option is intended for use with sockets that are configured
+     * in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
+     * only. The behavior of the {@code close} method when this option is
+     * enabled on a non-blocking socket is not defined.
+     *
+     * <p> The initial value of this socket option is a negative value, meaning
+     * that the option is disabled. The option may be enabled, or the linger
+     * interval changed, at any time. The maximum value of the linger interval
+     * is system dependent. Setting the linger interval to a value that is
+     * greater than its maximum value causes the linger interval to be set to
+     * its maximum value.
+     */
+    public static final SctpSocketOption<Integer> SO_LINGER =
+        new SctpStdSocketOption<Integer>("SO_LINGER", Integer.class,
+        sun.nio.ch.SctpStdSocketOption.SO_LINGER);
+
+    /**
+     * This class is used to set the maximum number of inbound/outbound streams
+     * used by the local endpoint during association initialization. An
+     * instance of this class is used to set the {@link
+     * SctpStandardSocketOptions#SCTP_INIT_MAXSTREAMS SCTP_INIT_MAXSTREAMS}
+     * socket option.
+     *
+     * @since 1.7
+     */
+    public static class InitMaxStreams {
+        private int maxInStreams;
+        private int maxOutStreams;
+
+        private InitMaxStreams(int maxInStreams, int maxOutStreams) {
+           this.maxInStreams = maxInStreams;
+           this.maxOutStreams = maxOutStreams;
+        }
+
+        /**
+         * Creates an InitMaxStreams instance.
+         *
+         * @param  maxInStreams
+         *         The maximum number of inbound streams, where
+         *         {@code 0 <= maxInStreams <= 65536}
+         *
+         * @param  maxOutStreams
+         *         The maximum number of outbound streams, where
+         *         {@code 0 <= maxOutStreams <= 65536}
+         *
+         * @return  An {@code InitMaxStreams} instance
+         *
+         * @throws  IllegalArgumentException
+         *          If an argument is outside of specified bounds
+         */
+        public static InitMaxStreams create
+              (int maxInStreams, int maxOutStreams) {
+            if (maxOutStreams < 0 || maxOutStreams > 65535)
+                throw new IllegalArgumentException(
+                      "Invalid maxOutStreams value");
+            if (maxInStreams < 0 || maxInStreams > 65535)
+                throw new IllegalArgumentException(
+                      "Invalid maxInStreams value");
+
+            return new InitMaxStreams(maxInStreams, maxOutStreams);
+        }
+
+        /**
+         * Returns the maximum number of inbound streams.
+         *
+         * @return  Maximum inbound streams
+         */
+        public int maxInStreams() {
+            return maxInStreams;
+        }
+
+        /**
+         * Returns the maximum number of outbound streams.
+         *
+         * @return  Maximum outbound streams
+         */
+        public int maxOutStreams() {
+            return maxOutStreams;
+        }
+
+        /**
+         * Returns a string representation of this init max streams, including
+         * the maximum in and out bound streams.
+         *
+         * @return  A string representation of this init max streams
+         */
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString()).append(" [");
+            sb.append("maxInStreams:").append(maxInStreams);
+            sb.append("maxOutStreams:").append(maxOutStreams).append("]");
+            return sb.toString();
+        }
+
+        /**
+         * Returns true if the specified object is another {@code InitMaxStreams}
+         * instance with the same number of in and out bound streams.
+         *
+         * @param  obj
+         *         The object to be compared with this init max streams
+         *
+         * @return  true if the specified object is another
+         *          {@code InitMaxStreams} instance with the same number of in
+         *          and out bound streams
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj != null && obj instanceof InitMaxStreams) {
+                InitMaxStreams that = (InitMaxStreams) obj;
+                if (this.maxInStreams == that.maxInStreams &&
+                    this.maxOutStreams == that.maxOutStreams)
+                    return true;
+            }
+            return false;
+        }
+
+        /**
+         * Returns a hash code value for this init max streams.
+         */
+        @Override
+        public int hashCode() {
+            int hash = 7 ^ maxInStreams ^ maxOutStreams;
+            return hash;
+        }
+    }
+}
--- a/jdk/src/share/classes/java/awt/Component.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/awt/Component.java	Wed May 18 13:19:32 2011 +0200
@@ -2887,11 +2887,12 @@
     /**
      * Invalidates this component and its ancestors.
      * <p>
-     * All the ancestors of this component up to the nearest validate root are
-     * marked invalid also. If there is no a validate root container for this
-     * component, all of its ancestors up to the root of the hierarchy are
-     * marked invalid as well. Marking a container <i>invalid</i> indicates
-     * that the container needs to be laid out.
+     * By default, all the ancestors of the component up to the top-most
+     * container of the hierarchy are marked invalid. If the {@code
+     * java.awt.smartInvalidate} system property is set to {@code true},
+     * invalidation stops on the nearest validate root of this component.
+     * Marking a container <i>invalid</i> indicates that the container needs to
+     * be laid out.
      * <p>
      * This method is called automatically when any layout-related information
      * changes (e.g. setting the bounds of the component, or adding the
--- a/jdk/src/share/classes/java/awt/Container.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/awt/Container.java	Wed May 18 13:19:32 2011 +0200
@@ -41,6 +41,8 @@
 import java.io.PrintStream;
 import java.io.PrintWriter;
 
+import java.security.AccessController;
+
 import java.util.Arrays;
 import java.util.EventListener;
 import java.util.HashSet;
@@ -60,6 +62,8 @@
 
 import sun.java2d.pipe.Region;
 
+import sun.security.action.GetBooleanAction;
+
 /**
  * A generic Abstract Window Toolkit(AWT) container object is a component
  * that can contain other AWT components.
@@ -1506,12 +1510,18 @@
      * Layout-related changes, such as bounds of the validate root descendants,
      * do not affect the layout of the validate root parent. This peculiarity
      * enables the {@code invalidate()} method to stop invalidating the
-     * component hierarchy when the method encounters a validate root.
+     * component hierarchy when the method encounters a validate root. However,
+     * to preserve backward compatibility this new optimized behavior is
+     * enabled only when the {@code java.awt.smartInvalidate} system property
+     * value is set to {@code true}.
      * <p>
-     * If a component hierarchy contains validate roots, the {@code validate()}
-     * method must be invoked on the validate root of a previously invalidated
-     * component, rather than on the top-level container (such as a {@code
-     * Frame} object) to restore the validity of the hierarchy later.
+     * If a component hierarchy contains validate roots and the new optimized
+     * {@code invalidate()} behavior is enabled, the {@code validate()} method
+     * must be invoked on the validate root of a previously invalidated
+     * component to restore the validity of the hierarchy later. Otherwise,
+     * calling the {@code validate()} method on the top-level container (such
+     * as a {@code Frame} object) should be used to restore the validity of the
+     * component hierarchy.
      * <p>
      * The {@code Window} class and the {@code Applet} class are the validate
      * roots in AWT.  Swing introduces more validate roots.
@@ -1527,13 +1537,20 @@
         return false;
     }
 
+    private static final boolean isJavaAwtSmartInvalidate;
+    static {
+        // Don't lazy-read because every app uses invalidate()
+        isJavaAwtSmartInvalidate = AccessController.doPrivileged(
+                new GetBooleanAction("java.awt.smartInvalidate"));
+    }
+
     /**
      * Invalidates the parent of the container unless the container
      * is a validate root.
      */
     @Override
     void invalidateParent() {
-        if (!isValidateRoot()) {
+        if (!isJavaAwtSmartInvalidate || !isValidateRoot()) {
             super.invalidateParent();
         }
     }
@@ -1572,9 +1589,8 @@
      * automatically.  Note that the ancestors of the container may be
      * invalidated also (see {@link Component#invalidate} for details.)
      * Therefore, to restore the validity of the hierarchy, the {@code
-     * validate()} method should be invoked on a validate root of an
-     * invalidated component, or on the top-most container if the hierarchy
-     * does not contain validate roots.
+     * validate()} method should be invoked on the top-most invalid
+     * container of the hierarchy.
      * <p>
      * Validating the container may be a quite time-consuming operation. For
      * performance reasons a developer may postpone the validation of the
--- a/jdk/src/share/classes/java/awt/Toolkit.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/awt/Toolkit.java	Wed May 18 13:19:32 2011 +0200
@@ -466,10 +466,7 @@
      */
     protected void loadSystemColors(int[] systemColors)
         throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
-
+        GraphicsEnvironment.checkHeadless();
     }
 
 /**
@@ -504,10 +501,7 @@
      */
     public void setDynamicLayout(boolean dynamic)
         throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
-
+        GraphicsEnvironment.checkHeadless();
     }
 
     /**
@@ -531,9 +525,8 @@
      */
     protected boolean isDynamicLayoutSet()
         throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
+
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().isDynamicLayoutSet();
         } else {
@@ -569,9 +562,8 @@
      */
     public boolean isDynamicLayoutActive()
         throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
+
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().isDynamicLayoutActive();
         } else {
@@ -615,9 +607,7 @@
      */
     public Insets getScreenInsets(GraphicsConfiguration gc)
         throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().getScreenInsets(gc);
         } else {
@@ -1200,10 +1190,7 @@
      * security manager's <code>checkPermission</code> method with a <code>
      * RuntimePermission("queuePrintJob")</code> permission.
      *
-     * @param   frame the parent of the print dialog. May be null if and only
-     *          if jobAttributes is not null and jobAttributes.getDialog()
-     *          returns JobAttributes.DialogType.NONE or
-     *          JobAttributes.DialogType.COMMON.
+     * @param   frame the parent of the print dialog. May not be null.
      * @param   jobtitle the title of the PrintJob. A null title is equivalent
      *          to "".
      * @param   jobAttributes a set of job attributes which will control the
@@ -1359,9 +1346,8 @@
      * @since 1.4
      */
     public Clipboard getSystemSelection() throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
+
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().getSystemSelection();
         } else {
@@ -1391,9 +1377,7 @@
      * @since     JDK1.1
      */
     public int getMenuShortcutKeyMask() throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
 
         return Event.CTRL_MASK;
     }
@@ -1418,7 +1402,10 @@
      * @since 1.3
      */
     public boolean getLockingKeyState(int keyCode)
-        throws UnsupportedOperationException {
+        throws UnsupportedOperationException
+    {
+        GraphicsEnvironment.checkHeadless();
+
         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
             throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState");
@@ -1449,7 +1436,10 @@
      * @since 1.3
      */
     public void setLockingKeyState(int keyCode, boolean on)
-        throws UnsupportedOperationException {
+        throws UnsupportedOperationException
+    {
+        GraphicsEnvironment.checkHeadless();
+
         if (! (keyCode == KeyEvent.VK_CAPS_LOCK || keyCode == KeyEvent.VK_NUM_LOCK ||
                keyCode == KeyEvent.VK_SCROLL_LOCK || keyCode == KeyEvent.VK_KANA_LOCK)) {
             throw new IllegalArgumentException("invalid key for Toolkit.setLockingKeyState");
@@ -1523,9 +1513,8 @@
      */
     public Dimension getBestCursorSize(int preferredWidth,
         int preferredHeight) throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
+
         // Override to implement custom cursor support.
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().
@@ -1553,9 +1542,8 @@
      * @since     1.2
      */
     public int getMaximumCursorColors() throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
+
         // Override to implement custom cursor support.
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().getMaximumCursorColors();
@@ -1605,9 +1593,8 @@
     public boolean isFrameStateSupported(int state)
         throws HeadlessException
     {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
+
         if (this != Toolkit.getDefaultToolkit()) {
             return Toolkit.getDefaultToolkit().
                 isFrameStateSupported(state);
@@ -2614,9 +2601,8 @@
     * @since 1.7
      */
     public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
-        if (GraphicsEnvironment.isHeadless()){
-            throw new HeadlessException();
-        }
+        GraphicsEnvironment.checkHeadless();
+
         return Toolkit.getDefaultToolkit().areExtraMouseButtonsEnabled();
     }
 }
--- a/jdk/src/share/classes/java/lang/SafeVarargs.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/SafeVarargs.java	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -32,7 +32,7 @@
  * constructor does not perform potentially unsafe operations on its
  * varargs parameter.  Applying this annotation to a method or
  * constructor suppresses unchecked warnings about a
- * <i>non-reifiable</i> variable-arity (vararg) type and suppresses
+ * <i>non-reifiable</i> variable arity (vararg) type and suppresses
  * unchecked warnings about parameterized array creation at call
  * sites.
  *
@@ -41,11 +41,10 @@
  * additional usage restrictions on this annotation type; it is a
  * compile-time error if a method or constructor declaration is
  * annotated with a {@code @SafeVarargs} annotation, and either:
-
  * <ul>
- * <li>  the declaration is a fixed-arity method or constructor
+ * <li>  the declaration is a fixed arity method or constructor
  *
- * <li> the declaration is a variable-arity method that is neither
+ * <li> the declaration is a variable arity method that is neither
  * {@code static} nor {@code final}.
  *
  * </ul>
@@ -55,15 +54,28 @@
  *
  * <ul>
  *
- * <li> The variable-arity parameter has a reifiable element type,
+ * <li> The variable arity parameter has a reifiable element type,
  * which includes primitive types, {@code Object}, and {@code String}.
  * (The unchecked warnings this annotation type suppresses already do
  * not occur for a reifiable element type.)
  *
  * <li> The body of the method or constructor declaration performs
  * potentially unsafe operations, such as an assignment to an element
- * of the variable-arity parameter's array that generates an unchecked
- * warning.
+ * of the variable arity parameter's array that generates an unchecked
+ * warning.  Some unsafe operations do not trigger an unchecked
+ * warning.  For example, the aliasing in
+ *
+ * <blockquote><pre>
+ * &#64;SafeVarargs // Not actually safe!
+ * static void m(List&lt;String&gt;... stringLists) {
+ *   Object[] array = stringLists;
+ *   List&lt;Integer&gt; tmpList = Arrays.asList(42);
+ *   array[0] = tmpList; // Semantically invalid, but compiles without warnings
+ *   String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime!
+ * }
+ * </pre></blockquote>
+ *
+ * leads to a {@code ClassCastException} at runtime.
  *
  * <p>Future versions of the platform may mandate compiler errors for
  * such unsafe operations.
--- a/jdk/src/share/classes/java/lang/Throwable.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/Throwable.java	Wed May 18 13:19:32 2011 +0200
@@ -336,7 +336,10 @@
      * Disabling of suppression should only occur in exceptional
      * circumstances where special requirements exist, such as a
      * virtual machine reusing exception objects under low-memory
-     * situations.
+     * situations.  Circumstances where a given exception object is
+     * repeatedly caught and rethrown, such as to implement control
+     * flow between two sub-systems, is another situation where
+     * immutable throwable objects would be appropriate.
      *
      * @param  message the detail message.
      * @param cause the cause.  (A {@code null} value is permitted,
@@ -423,6 +426,18 @@
      * {@link #Throwable(String,Throwable)}, this method cannot be called
      * even once.
      *
+     * <p>An example of using this method on a legacy throwable type
+     * without other support for setting the cause is:
+     *
+     * <pre>
+     * try {
+     *     lowLevelOp();
+     * } catch (LowLevelException le) {
+     *     throw (HighLevelException)
+     *           new HighLevelException().initCause(le); // Legacy constructor
+     * }
+     * </pre>
+     *
      * @param  cause the cause (which is saved for later retrieval by the
      *         {@link #getCause()} method).  (A {@code null} value is
      *         permitted, and indicates that the cause is nonexistent or
@@ -762,7 +777,8 @@
      * @see     java.lang.Throwable#printStackTrace()
      */
     public synchronized Throwable fillInStackTrace() {
-        if (stackTrace != null) {
+        if (stackTrace != null ||
+            backtrace != null /* Out of protocol state */ ) {
             fillInStackTrace(0);
             stackTrace = UNASSIGNED_STACK;
         }
@@ -788,7 +804,8 @@
      * this throwable is permitted to return a zero-length array from this
      * method.  Generally speaking, the array returned by this method will
      * contain one element for every frame that would be printed by
-     * {@code printStackTrace}.
+     * {@code printStackTrace}.  Writes to the returned array do not
+     * affect future calls to this method.
      *
      * @return an array of stack trace elements representing the stack trace
      *         pertaining to this throwable.
@@ -801,7 +818,8 @@
     private synchronized StackTraceElement[] getOurStackTrace() {
         // Initialize stack trace field with information from
         // backtrace if this is the first call to this method
-        if (stackTrace == UNASSIGNED_STACK) {
+        if (stackTrace == UNASSIGNED_STACK ||
+            (stackTrace == null && backtrace != null) /* Out of protocol state */) {
             int depth = getStackTraceDepth();
             stackTrace = new StackTraceElement[depth];
             for (int i=0; i < depth; i++)
@@ -849,7 +867,8 @@
         }
 
         synchronized (this) {
-            if (this.stackTrace == null) // Immutable stack
+            if (this.stackTrace == null && // Immutable stack
+                backtrace == null) // Test for out of protocol state
                 return;
             this.stackTrace = defensiveCopy;
         }
@@ -971,8 +990,8 @@
     /**
      * Appends the specified exception to the exceptions that were
      * suppressed in order to deliver this exception. This method is
-     * typically called (automatically and implicitly) by the {@code
-     * try}-with-resources statement.
+     * thread-safe and typically called (automatically and implicitly)
+     * by the {@code try}-with-resources statement.
      *
      * <p>The suppression behavior is enabled <em>unless</em> disabled
      * {@linkplain #Throwable(String, Throwable, boolean, boolean) via
@@ -1043,7 +1062,9 @@
      *
      * If no exceptions were suppressed or {@linkplain
      * #Throwable(String, Throwable, boolean, boolean) suppression is
-     * disabled}, an empty array is returned.
+     * disabled}, an empty array is returned.  This method is
+     * thread-safe.  Writes to the returned array do not affect future
+     * calls to this method.
      *
      * @return an array containing all of the exceptions that were
      *         suppressed to deliver this exception.
--- a/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java	Wed May 18 13:19:32 2011 +0200
@@ -27,6 +27,7 @@
 
 import sun.invoke.util.VerifyType;
 import sun.invoke.util.Wrapper;
+import sun.invoke.util.ValueConversions;
 import java.util.Arrays;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.*;
@@ -55,29 +56,35 @@
         this(target, newType, conv, null);
     }
 
+    int getConversion() { return conversion; }
+
     // TO DO:  When adapting another MH with a null conversion, clone
     // the target and change its type, instead of adding another layer.
 
     /** Can a JVM-level adapter directly implement the proposed
      *  argument conversions, as if by MethodHandles.convertArguments?
      */
-    static boolean canPairwiseConvert(MethodType newType, MethodType oldType) {
+    static boolean canPairwiseConvert(MethodType newType, MethodType oldType, int level) {
         // same number of args, of course
         int len = newType.parameterCount();
         if (len != oldType.parameterCount())
             return false;
 
-        // Check return type.  (Not much can be done with it.)
+        // Check return type.
         Class<?> exp = newType.returnType();
         Class<?> ret = oldType.returnType();
-        if (!VerifyType.isNullConversion(ret, exp))
-            return false;
+        if (!VerifyType.isNullConversion(ret, exp)) {
+            if (!convOpSupported(OP_COLLECT_ARGS))
+                return false;
+            if (!canConvertArgument(ret, exp, level))
+                return false;
+        }
 
         // Check args pairwise.
         for (int i = 0; i < len; i++) {
             Class<?> src = newType.parameterType(i); // source type
             Class<?> dst = oldType.parameterType(i); // destination type
-            if (!canConvertArgument(src, dst))
+            if (!canConvertArgument(src, dst, level))
                 return false;
         }
 
@@ -87,11 +94,14 @@
     /** Can a JVM-level adapter directly implement the proposed
      *  argument conversion, as if by MethodHandles.convertArguments?
      */
-    static boolean canConvertArgument(Class<?> src, Class<?> dst) {
+    static boolean canConvertArgument(Class<?> src, Class<?> dst, int level) {
         // ? Retool this logic to use RETYPE_ONLY, CHECK_CAST, etc., as opcodes,
         // so we don't need to repeat so much decision making.
         if (VerifyType.isNullConversion(src, dst)) {
             return true;
+        } else if (convOpSupported(OP_COLLECT_ARGS)) {
+            // If we can build filters, we can convert anything to anything.
+            return true;
         } else if (src.isPrimitive()) {
             if (dst.isPrimitive())
                 return canPrimCast(src, dst);
@@ -99,7 +109,7 @@
                 return canBoxArgument(src, dst);
         } else {
             if (dst.isPrimitive())
-                return canUnboxArgument(src, dst);
+                return canUnboxArgument(src, dst, level);
             else
                 return true;  // any two refs can be interconverted
         }
@@ -109,21 +119,20 @@
      * Create a JVM-level adapter method handle to conform the given method
      * handle to the similar newType, using only pairwise argument conversions.
      * For each argument, convert incoming argument to the exact type needed.
-     * Only null conversions are allowed on the return value (until
-     * the JVM supports ricochet adapters).
-     * The argument conversions allowed are casting, unboxing,
+     * The argument conversions allowed are casting, boxing and unboxing,
      * integral widening or narrowing, and floating point widening or narrowing.
      * @param newType required call type
      * @param target original method handle
+     * @param level which strength of conversion is allowed
      * @return an adapter to the original handle with the desired new type,
      *          or the original target if the types are already identical
      *          or null if the adaptation cannot be made
      */
-    static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target) {
+    static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target, int level) {
         MethodType oldType = target.type();
         if (newType == oldType)  return target;
 
-        if (!canPairwiseConvert(newType, oldType))
+        if (!canPairwiseConvert(newType, oldType, level))
             return null;
         // (after this point, it is an assertion error to fail to convert)
 
@@ -138,9 +147,14 @@
                 break;
             }
         }
+
+        Class<?> needReturn = newType.returnType();
+        Class<?> haveReturn = oldType.returnType();
+        boolean retConv = !VerifyType.isNullConversion(haveReturn, needReturn);
+
         // Now build a chain of one or more adapters.
-        MethodHandle adapter = target;
-        MethodType midType = oldType.changeReturnType(newType.returnType());
+        MethodHandle adapter = target, adapter2;
+        MethodType midType = oldType;
         for (int i = 0; i <= lastConv; i++) {
             Class<?> src = newType.parameterType(i); // source type
             Class<?> dst = midType.parameterType(i); // destination type
@@ -149,22 +163,23 @@
                 continue;
             }
             // Work the current type backward toward the desired caller type:
-            if (i != lastConv) {
-                midType = midType.changeParameterType(i, src);
-            } else {
+            midType = midType.changeParameterType(i, src);
+            if (i == lastConv) {
                 // When doing the last (or only) real conversion,
                 // force all remaining null conversions to happen also.
-                assert(VerifyType.isNullConversion(newType, midType.changeParameterType(i, src)));
-                midType = newType;
+                MethodType lastMidType = newType;
+                if (retConv)  lastMidType = lastMidType.changeReturnType(haveReturn);
+                assert(VerifyType.isNullConversion(lastMidType, midType));
+                midType = lastMidType;
             }
 
             // Tricky case analysis follows.
             // It parallels canConvertArgument() above.
             if (src.isPrimitive()) {
                 if (dst.isPrimitive()) {
-                    adapter = makePrimCast(midType, adapter, i, dst);
+                    adapter2 = makePrimCast(midType, adapter, i, dst);
                 } else {
-                    adapter = makeBoxArgument(midType, adapter, i, dst);
+                    adapter2 = makeBoxArgument(midType, adapter, i, src);
                 }
             } else {
                 if (dst.isPrimitive()) {
@@ -174,29 +189,53 @@
                     // conversions supported by reflect.Method.invoke.
                     // Those conversions require a big nest of if/then/else logic,
                     // which we prefer to make a user responsibility.
-                    adapter = makeUnboxArgument(midType, adapter, i, dst);
+                    adapter2 = makeUnboxArgument(midType, adapter, i, dst, level);
                 } else {
                     // Simple reference conversion.
                     // Note:  Do not check for a class hierarchy relation
                     // between src and dst.  In all cases a 'null' argument
                     // will pass the cast conversion.
-                    adapter = makeCheckCast(midType, adapter, i, dst);
+                    adapter2 = makeCheckCast(midType, adapter, i, dst);
                 }
             }
-            assert(adapter != null);
-            assert(adapter.type() == midType);
+            assert(adapter2 != null) : Arrays.asList(src, dst, midType, adapter, i, target, newType);
+            assert(adapter2.type() == midType);
+            adapter = adapter2;
+        }
+        if (retConv) {
+            adapter2 = makeReturnConversion(adapter, haveReturn, needReturn);
+            assert(adapter2 != null);
+            adapter = adapter2;
         }
         if (adapter.type() != newType) {
             // Only trivial conversions remain.
-            adapter = makeRetypeOnly(newType, adapter);
-            assert(adapter != null);
+            adapter2 = makeRetypeOnly(newType, adapter);
+            assert(adapter2 != null);
+            adapter = adapter2;
             // Actually, that's because there were no non-trivial ones:
-            assert(lastConv == -1);
+            assert(lastConv == -1 || retConv);
         }
         assert(adapter.type() == newType);
         return adapter;
     }
 
+    private static MethodHandle makeReturnConversion(MethodHandle target, Class<?> haveReturn, Class<?> needReturn) {
+        MethodHandle adjustReturn;
+        if (haveReturn == void.class) {
+            // synthesize a zero value for the given void
+            Object zero = Wrapper.forBasicType(needReturn).zero();
+            adjustReturn = MethodHandles.constant(needReturn, zero);
+        } else {
+            MethodType needConversion = MethodType.methodType(needReturn, haveReturn);
+            adjustReturn = MethodHandles.identity(needReturn).asType(needConversion);
+        }
+        if (!canCollectArguments(adjustReturn.type(), target.type(), 0, false)) {
+            assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
+            throw new InternalError("NYI");
+        }
+        return makeCollectArguments(adjustReturn, target, 0, false);
+    }
+
     /**
      * Create a JVM-level adapter method handle to permute the arguments
      * of the given method.
@@ -224,7 +263,7 @@
         if (argumentMap.length != oldType.parameterCount())
             throw newIllegalArgumentException("bad permutation: "+Arrays.toString(argumentMap));
         if (nullPermutation) {
-            MethodHandle res = makePairwiseConvert(newType, target);
+            MethodHandle res = makePairwiseConvert(newType, target, 0);
             // well, that was easy
             if (res == null)
                 throw newIllegalArgumentException("cannot convert pairwise: "+newType);
@@ -310,11 +349,25 @@
         return (spChange & CONV_STACK_MOVE_MASK) << CONV_STACK_MOVE_SHIFT;
     }
 
+    static int extractStackMove(int convOp) {
+        int spChange = convOp >> CONV_STACK_MOVE_SHIFT;
+        return spChange / MethodHandleNatives.JVM_STACK_MOVE_UNIT;
+    }
+
+    static int extractStackMove(MethodHandle target) {
+        if (target instanceof AdapterMethodHandle) {
+            AdapterMethodHandle amh = (AdapterMethodHandle) target;
+            return extractStackMove(amh.getConversion());
+        } else {
+            return 0;
+        }
+    }
+
     /** Construct an adapter conversion descriptor for a single-argument conversion. */
     private static long makeConv(int convOp, int argnum, int src, int dest) {
-        assert(src  == (src  & 0xF));
-        assert(dest == (dest & 0xF));
-        assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF);
+        assert(src  == (src  & CONV_TYPE_MASK));
+        assert(dest == (dest & CONV_TYPE_MASK));
+        assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF || convOp == OP_COLLECT_ARGS);
         int stackMove = type2size(dest) - type2size(src);
         return ((long) argnum << 32 |
                 (long) convOp << CONV_OP_SHIFT |
@@ -323,11 +376,10 @@
                 insertStackMove(stackMove)
                 );
     }
-    private static long makeConv(int convOp, int argnum, int stackMove) {
-        assert(convOp >= OP_DUP_ARGS && convOp <= OP_SPREAD_ARGS);
+    private static long makeDupConv(int convOp, int argnum, int stackMove) {
+        // simple argument motion, requiring one slot to specify
+        assert(convOp == OP_DUP_ARGS || convOp == OP_DROP_ARGS);
         byte src = 0, dest = 0;
-        if (convOp >= OP_COLLECT_ARGS && convOp <= OP_SPREAD_ARGS)
-            src = dest = T_OBJECT;
         return ((long) argnum << 32 |
                 (long) convOp << CONV_OP_SHIFT |
                 (int)  src    << CONV_SRC_TYPE_SHIFT |
@@ -336,7 +388,8 @@
                 );
     }
     private static long makeSwapConv(int convOp, int srcArg, byte type, int destSlot) {
-        assert(convOp >= OP_SWAP_ARGS && convOp <= OP_ROT_ARGS);
+        // more complex argument motion, requiring two slots to specify
+        assert(convOp == OP_SWAP_ARGS || convOp == OP_ROT_ARGS);
         return ((long) srcArg << 32 |
                 (long) convOp << CONV_OP_SHIFT |
                 (int)  type   << CONV_SRC_TYPE_SHIFT |
@@ -344,6 +397,18 @@
                 (int)  destSlot << CONV_VMINFO_SHIFT
                 );
     }
+    private static long makeSpreadConv(int convOp, int argnum, int src, int dest, int stackMove) {
+        // spreading or collecting, at a particular slot location
+        assert(convOp == OP_SPREAD_ARGS || convOp == OP_COLLECT_ARGS || convOp == OP_FOLD_ARGS);
+        // src  = spread ? T_OBJECT (for array)  : common type of collected args (else void)
+        // dest = spread ? element type of array : result type of collector (can be void)
+        return ((long) argnum << 32 |
+                (long) convOp << CONV_OP_SHIFT |
+                (int)  src    << CONV_SRC_TYPE_SHIFT |
+                (int)  dest   << CONV_DEST_TYPE_SHIFT |
+                insertStackMove(stackMove)
+                );
+    }
     private static long makeConv(int convOp) {
         assert(convOp == OP_RETYPE_ONLY || convOp == OP_RETYPE_RAW);
         return ((long)-1 << 32) | (convOp << CONV_OP_SHIFT);   // stackMove, src, dst all zero
@@ -570,14 +635,10 @@
     static boolean canPrimCast(Class<?> src, Class<?> dst) {
         if (src == dst || !src.isPrimitive() || !dst.isPrimitive()) {
             return false;
-        } else if (Wrapper.forPrimitiveType(dst).isFloating()) {
-            // both must be floating types
-            return Wrapper.forPrimitiveType(src).isFloating();
         } else {
-            // both are integral, and all combinations work fine
-            assert(Wrapper.forPrimitiveType(src).isIntegral() &&
-                   Wrapper.forPrimitiveType(dst).isIntegral());
-            return true;
+            boolean sflt = Wrapper.forPrimitiveType(src).isFloating();
+            boolean dflt = Wrapper.forPrimitiveType(dst).isFloating();
+            return !(sflt | dflt);  // no float support at present
         }
     }
 
@@ -589,6 +650,29 @@
      */
     static MethodHandle makePrimCast(MethodType newType, MethodHandle target,
                 int arg, Class<?> convType) {
+        Class<?> src = newType.parameterType(arg);
+        if (canPrimCast(src, convType))
+            return makePrimCastOnly(newType, target, arg, convType);
+        Class<?> dst = convType;
+        boolean sflt = Wrapper.forPrimitiveType(src).isFloating();
+        boolean dflt = Wrapper.forPrimitiveType(dst).isFloating();
+        if (sflt | dflt) {
+            MethodHandle convMethod;
+            if (sflt)
+                convMethod = ((src == double.class)
+                        ? ValueConversions.convertFromDouble(dst)
+                        : ValueConversions.convertFromFloat(dst));
+            else
+                convMethod = ((dst == double.class)
+                        ? ValueConversions.convertToDouble(src)
+                        : ValueConversions.convertToFloat(src));
+            long conv = makeConv(OP_COLLECT_ARGS, arg, basicType(src), basicType(dst));
+            return new AdapterMethodHandle(target, newType, conv, convMethod);
+        }
+        throw new InternalError("makePrimCast");
+    }
+    static MethodHandle makePrimCastOnly(MethodType newType, MethodHandle target,
+                int arg, Class<?> convType) {
         MethodType oldType = target.type();
         if (!canPrimCast(newType, oldType, arg, convType))
             return null;
@@ -602,7 +686,7 @@
      *  The convType is the unboxed type; it can be either a primitive or wrapper.
      */
     static boolean canUnboxArgument(MethodType newType, MethodType targetType,
-                int arg, Class<?> convType) {
+                int arg, Class<?> convType, int level) {
         if (!convOpSupported(OP_REF_TO_PRIM))  return false;
         Class<?> src = newType.parameterType(arg);
         Class<?> dst = targetType.parameterType(arg);
@@ -616,21 +700,31 @@
         return (diff == arg+1);  // arg is sole non-trivial diff
     }
     /** Can an primitive unboxing adapter validly convert src to dst? */
-    static boolean canUnboxArgument(Class<?> src, Class<?> dst) {
-        return (!src.isPrimitive() && Wrapper.asPrimitiveType(dst).isPrimitive());
+    static boolean canUnboxArgument(Class<?> src, Class<?> dst, int level) {
+        assert(dst.isPrimitive());
+        // if we have JVM support for boxing, we can also do complex unboxing
+        if (convOpSupported(OP_PRIM_TO_REF))  return true;
+        Wrapper dw = Wrapper.forPrimitiveType(dst);
+        // Level 0 means cast and unbox.  This works on any reference.
+        if (level == 0)  return !src.isPrimitive();
+        assert(level >= 0 && level <= 2);
+        // Levels 1 and 2 allow widening and/or narrowing conversions.
+        // These are not supported directly by the JVM.
+        // But if the input reference is monomorphic, we can do it.
+        return dw.wrapperType() == src;
     }
 
     /** Factory method:  Unbox the given argument.
      *  Return null if this cannot be done.
      */
     static MethodHandle makeUnboxArgument(MethodType newType, MethodHandle target,
-                int arg, Class<?> convType) {
+                int arg, Class<?> convType, int level) {
         MethodType oldType = target.type();
         Class<?> src = newType.parameterType(arg);
         Class<?> dst = oldType.parameterType(arg);
         Class<?> boxType = Wrapper.asWrapperType(convType);
         Class<?> primType = Wrapper.asPrimitiveType(convType);
-        if (!canUnboxArgument(newType, oldType, arg, convType))
+        if (!canUnboxArgument(newType, oldType, arg, convType, level))
             return null;
         MethodType castDone = newType;
         if (!VerifyType.isNullConversion(src, boxType))
@@ -642,19 +736,46 @@
         return makeCheckCast(newType, adapter, arg, boxType);
     }
 
+    /** Can a boxing conversion validly convert src to dst? */
+    static boolean canBoxArgument(MethodType newType, MethodType targetType,
+                int arg, Class<?> convType) {
+        if (!convOpSupported(OP_PRIM_TO_REF))  return false;
+        Class<?> src = newType.parameterType(arg);
+        Class<?> dst = targetType.parameterType(arg);
+        Class<?> boxType = Wrapper.asWrapperType(convType);
+        convType = Wrapper.asPrimitiveType(convType);
+        if (!canCheckCast(boxType, dst)
+                || boxType == convType
+                || !VerifyType.isNullConversion(src, convType))
+            return false;
+        int diff = diffTypes(newType, targetType, false);
+        return (diff == arg+1);  // arg is sole non-trivial diff
+    }
+
     /** Can an primitive boxing adapter validly convert src to dst? */
     static boolean canBoxArgument(Class<?> src, Class<?> dst) {
         if (!convOpSupported(OP_PRIM_TO_REF))  return false;
-        throw new UnsupportedOperationException("NYI");
+        return (src.isPrimitive() && !dst.isPrimitive());
     }
 
-    /** Factory method:  Unbox the given argument.
+    /** Factory method:  Box the given argument.
      *  Return null if this cannot be done.
      */
     static MethodHandle makeBoxArgument(MethodType newType, MethodHandle target,
                 int arg, Class<?> convType) {
-        // this is difficult to do in the JVM because it must GC
-        return null;
+        MethodType oldType = target.type();
+        Class<?> src = newType.parameterType(arg);
+        Class<?> dst = oldType.parameterType(arg);
+        Class<?> boxType = Wrapper.asWrapperType(convType);
+        Class<?> primType = Wrapper.asPrimitiveType(convType);
+        if (!canBoxArgument(newType, oldType, arg, convType)) {
+            return null;
+        }
+        if (!VerifyType.isNullConversion(boxType, dst))
+            target = makeCheckCast(oldType.changeParameterType(arg, boxType), target, arg, dst);
+        MethodHandle boxerMethod = ValueConversions.box(Wrapper.forPrimitiveType(primType));
+        long conv = makeConv(OP_PRIM_TO_REF, arg, basicType(primType), T_OBJECT);
+        return new AdapterMethodHandle(target, newType, conv, boxerMethod);
     }
 
     /** Can an adapter simply drop arguments to convert the target to newType? */
@@ -699,7 +820,7 @@
         int slotCount   = keep1InSlot - dropSlot;
         assert(slotCount >= dropArgCount);
         assert(target.type().parameterSlotCount() + slotCount == newType.parameterSlotCount());
-        long conv = makeConv(OP_DROP_ARGS, dropArgPos + dropArgCount - 1, -slotCount);
+        long conv = makeDupConv(OP_DROP_ARGS, dropArgPos + dropArgCount - 1, -slotCount);
         return new AdapterMethodHandle(target, newType, conv);
     }
 
@@ -739,7 +860,7 @@
         int keep1InSlot = newType.parameterSlotDepth(dupArgPos);
         int slotCount   = keep1InSlot - dupSlot;
         assert(target.type().parameterSlotCount() - slotCount == newType.parameterSlotCount());
-        long conv = makeConv(OP_DUP_ARGS, dupArgPos + dupArgCount - 1, slotCount);
+        long conv = makeDupConv(OP_DUP_ARGS, dupArgPos + dupArgCount - 1, slotCount);
         return new AdapterMethodHandle(target, newType, conv);
     }
 
@@ -900,7 +1021,7 @@
         for (int i = 0; i < spreadArgCount; i++) {
             Class<?> src = VerifyType.spreadArgElementType(spreadArgType, i);
             Class<?> dst = targetType.parameterType(spreadArgPos + i);
-            if (src == null || !VerifyType.isNullConversion(src, dst))
+            if (src == null || !canConvertArgument(src, dst, 1))
                 return false;
         }
         return true;
@@ -910,24 +1031,100 @@
     /** Factory method:  Spread selected argument. */
     static MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target,
                 Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
+        // FIXME: Get rid of newType; derive new arguments from structure of spreadArgType
         MethodType targetType = target.type();
         if (!canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
             return null;
+        // dest is not significant; remove?
+        int dest = T_VOID;
+        for (int i = 0; i < spreadArgCount; i++) {
+            Class<?> arg = VerifyType.spreadArgElementType(spreadArgType, i);
+            if (arg == null)  arg = Object.class;
+            int dest2 = basicType(arg);
+            if      (dest == T_VOID)  dest = dest2;
+            else if (dest != dest2)   dest = T_VOID;
+            if (dest == T_VOID)  break;
+            targetType = targetType.changeParameterType(spreadArgPos + i, arg);
+        }
+        target = target.asType(targetType);
+        int arrayArgSize = 1;  // always a reference
         // in  arglist: [0: ...keep1 | spos: spreadArg | spos+1:      keep2... ]
         // out arglist: [0: ...keep1 | spos: spread... | spos+scount: keep2... ]
         int keep2OutPos  = spreadArgPos + spreadArgCount;
-        int spreadSlot   = targetType.parameterSlotDepth(keep2OutPos);
-        int keep1OutSlot = targetType.parameterSlotDepth(spreadArgPos);
-        int slotCount    = keep1OutSlot - spreadSlot;
-        assert(spreadSlot == newType.parameterSlotDepth(spreadArgPos+1));
+        int keep1OutSlot = targetType.parameterSlotDepth(spreadArgPos);   // leading edge of |spread...|
+        int spreadSlot   = targetType.parameterSlotDepth(keep2OutPos);    // trailing edge of |spread...|
+        assert(spreadSlot == newType.parameterSlotDepth(spreadArgPos+arrayArgSize));
+        int slotCount    = keep1OutSlot - spreadSlot;                     // slots in |spread...|
         assert(slotCount >= spreadArgCount);
-        long conv = makeConv(OP_SPREAD_ARGS, spreadArgPos, slotCount-1);
+        int stackMove = - arrayArgSize + slotCount;  // pop array, push N slots
+        long conv = makeSpreadConv(OP_SPREAD_ARGS, spreadArgPos, T_OBJECT, dest, stackMove);
         MethodHandle res = new AdapterMethodHandle(target, newType, conv, spreadArgType);
         assert(res.type().parameterType(spreadArgPos) == spreadArgType);
         return res;
     }
 
-    // TO DO: makeCollectArguments, makeFlyby, makeRicochet
+    /** Can an adapter collect a series of arguments, replacing them by zero or one results? */
+    static boolean canCollectArguments(MethodType targetType,
+                MethodType collectorType, int collectArgPos, boolean retainOriginalArgs) {
+        if (!convOpSupported(retainOriginalArgs ? OP_FOLD_ARGS : OP_COLLECT_ARGS))  return false;
+        int collectArgCount = collectorType.parameterCount();
+        Class<?> rtype = collectorType.returnType();
+        assert(rtype == void.class || targetType.parameterType(collectArgPos) == rtype)
+                // [(Object)Object[], (Object[])Object[], 0, 1]
+                : Arrays.asList(targetType, collectorType, collectArgPos, collectArgCount)
+                ;
+        return true;
+    }
+
+    /** Factory method:  Collect or filter selected argument(s). */
+    static MethodHandle makeCollectArguments(MethodHandle target,
+                MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
+        assert(canCollectArguments(target.type(), collector.type(), collectArgPos, retainOriginalArgs));
+        MethodType targetType = target.type();
+        MethodType collectorType = collector.type();
+        int collectArgCount = collectorType.parameterCount();
+        Class<?> collectValType = collectorType.returnType();
+        int collectValCount = (collectValType == void.class ? 0 : 1);
+        int collectValSlots = collectorType.returnSlotCount();
+        MethodType newType = targetType
+                .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
+        if (!retainOriginalArgs) {
+            newType = newType
+                .insertParameterTypes(collectArgPos, collectorType.parameterList());
+        } else {
+            // parameter types at the fold point must be the same
+            assert(diffParamTypes(newType, collectArgPos, targetType, collectValCount, collectArgCount, false) == 0)
+                : Arrays.asList(target, collector, collectArgPos, retainOriginalArgs);
+        }
+        // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
+        // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
+        // out(retain): [0: ...keep1 | cpos: cV? coll... | cpos+cvc+cac: keep2... ]
+        int keep2InPos   = collectArgPos + collectArgCount;
+        int keep1InSlot  = newType.parameterSlotDepth(collectArgPos);  // leading edge of |collect...|
+        int collectSlot  = newType.parameterSlotDepth(keep2InPos);     // trailing edge of |collect...|
+        int slotCount    = keep1InSlot - collectSlot;                  // slots in |collect...|
+        assert(slotCount >= collectArgCount);
+        assert(collectSlot == targetType.parameterSlotDepth(
+                collectArgPos + collectValCount + (retainOriginalArgs ? collectArgCount : 0) ));
+        int dest = basicType(collectValType);
+        int src = T_VOID;
+        // src is not significant; remove?
+        for (int i = 0; i < collectArgCount; i++) {
+            int src2 = basicType(collectorType.parameterType(i));
+            if      (src == T_VOID)  src = src2;
+            else if (src != src2)    src = T_VOID;
+            if (src == T_VOID)  break;
+        }
+        int stackMove = collectValSlots;  // push 0..2 results
+        if (!retainOriginalArgs)  stackMove -= slotCount; // pop N arguments
+        int lastCollectArg = keep2InPos-1;
+        long conv = makeSpreadConv(retainOriginalArgs ? OP_FOLD_ARGS : OP_COLLECT_ARGS,
+                                   lastCollectArg, src, dest, stackMove);
+        MethodHandle res = new AdapterMethodHandle(target, newType, conv, collector);
+        assert(res.type().parameterList().subList(collectArgPos, collectArgPos+collectArgCount)
+                .equals(collector.type().parameterList()));
+        return res;
+    }
 
     @Override
     public String toString() {
--- a/jdk/src/share/classes/java/lang/invoke/CallSite.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java	Wed May 18 13:19:32 2011 +0200
@@ -273,9 +273,9 @@
             Object binding;
             info = maybeReBox(info);
             if (info == null) {
-                binding = bootstrapMethod.invokeGeneric(caller, name, type);
+                binding = bootstrapMethod.invoke(caller, name, type);
             } else if (!info.getClass().isArray()) {
-                binding = bootstrapMethod.invokeGeneric(caller, name, type, info);
+                binding = bootstrapMethod.invoke(caller, name, type, info);
             } else {
                 Object[] argv = (Object[]) info;
                 maybeReBoxElements(argv);
@@ -283,10 +283,10 @@
                     throw new BootstrapMethodError("too many bootstrap method arguments");
                 MethodType bsmType = bootstrapMethod.type();
                 if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
-                    binding = bootstrapMethod.invokeGeneric(caller, name, type, argv);
+                    binding = bootstrapMethod.invoke(caller, name, type, argv);
                 else
                     binding = MethodHandles.spreadInvoker(bsmType, 3)
-                        .invokeGeneric(bootstrapMethod, caller, name, type, argv);
+                        .invoke(bootstrapMethod, caller, name, type, argv);
             }
             //System.out.println("BSM for "+name+type+" => "+binding);
             if (binding instanceof CallSite) {
--- a/jdk/src/share/classes/java/lang/invoke/FilterGeneric.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/FilterGeneric.java	Wed May 18 13:19:32 2011 +0200
@@ -61,6 +61,10 @@
         return ad;
     }
 
+    static {
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
+    }
+
     Adapter makeInstance(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
         Adapter ad = getAdapter(kind, pos);
         return ad.makeInstance(ad.prototypeEntryPoint(), filter, target);
--- a/jdk/src/share/classes/java/lang/invoke/FilterOneArgument.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/FilterOneArgument.java	Wed May 18 13:19:32 2011 +0200
@@ -67,6 +67,10 @@
         this.target = target;
     }
 
+    static {
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
+    }
+
     public static MethodHandle make(MethodHandle filter, MethodHandle target) {
         if (filter == null)  return target;
         if (target == null)  return filter;
--- a/jdk/src/share/classes/java/lang/invoke/FromGeneric.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/FromGeneric.java	Wed May 18 13:19:32 2011 +0200
@@ -98,6 +98,10 @@
         this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
     }
 
+    static {
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
+    }
+
     /**
      * The typed target will be called according to targetType.
      * The adapter code will in fact see the raw result from internalType,
@@ -112,10 +116,10 @@
             assert(iret == Object.class);
             return ValueConversions.identity();
         } else if (wrap.primitiveType() == iret) {
-            return ValueConversions.box(wrap, false);
+            return ValueConversions.box(wrap);
         } else {
             assert(tret == double.class ? iret == long.class : iret == int.class);
-            return ValueConversions.boxRaw(wrap, false);
+            return ValueConversions.boxRaw(wrap);
         }
     }
 
@@ -135,7 +139,7 @@
         MethodType fixArgsType = internalType.changeReturnType(targetType.returnType());
         MethodHandle fixArgs = MethodHandleImpl.convertArguments(
                                  invoker, Invokers.invokerType(fixArgsType),
-                                 invoker.type(), null);
+                                 invoker.type(), 0);
         if (fixArgs == null)
             throw new InternalError("bad fixArgs");
         // reinterpret the calling sequence as raw:
@@ -160,7 +164,6 @@
     /** Build an adapter of the given generic type, which invokes typedTarget
      *  on the incoming arguments, after unboxing as necessary.
      *  The return value is boxed if necessary.
-     * @param genericType  the required type of the result
      * @param typedTarget the target
      * @return an adapter method handle
      */
@@ -231,7 +234,7 @@
     }
 
     static Adapter buildAdapterFromBytecodes(MethodType internalType) {
-        throw new UnsupportedOperationException("NYI");
+        throw new UnsupportedOperationException("NYI "+internalType);
     }
 
     /**
--- a/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java	Wed May 18 13:19:32 2011 +0200
@@ -29,12 +29,12 @@
 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
 
 /**
- * Adapters which manage MethodHandle.invokeGeneric calls.
+ * 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 invokeGeneric site
+    // 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;
@@ -56,7 +56,7 @@
     }
 
     /** Return the adapter information for this type's erasure. */
-    /*non-public*/ static MethodHandle genericInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException {
+    /*non-public*/ static MethodHandle generalInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException {
         InvokeGeneric gen = new InvokeGeneric(erasedCallerType);
         return gen.initialInvoker;
     }
--- a/jdk/src/share/classes/java/lang/invoke/Invokers.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java	Wed May 18 13:19:32 2011 +0200
@@ -43,10 +43,10 @@
     private /*lazy*/ MethodHandle erasedInvoker;
     /*lazy*/ MethodHandle erasedInvokerWithDrops;  // for InvokeGeneric
 
-    // generic (untyped) invoker for the outgoing call
-    private /*lazy*/ MethodHandle genericInvoker;
+    // general invoker for the outgoing call
+    private /*lazy*/ MethodHandle generalInvoker;
 
-    // generic (untyped) invoker for the outgoing call; accepts a single Object[]
+    // general invoker for the outgoing call; accepts a single Object[]
     private final /*lazy*/ MethodHandle[] spreadInvokers;
 
     // invoker for an unbound callsite
@@ -77,13 +77,13 @@
         return invoker;
     }
 
-    /*non-public*/ MethodHandle genericInvoker() {
+    /*non-public*/ MethodHandle generalInvoker() {
         MethodHandle invoker1 = exactInvoker();
-        MethodHandle invoker = genericInvoker;
+        MethodHandle invoker = generalInvoker;
         if (invoker != null)  return invoker;
-        MethodType genericType = targetType.generic();
-        invoker = MethodHandles.convertArguments(invoker1, invokerType(genericType));
-        genericInvoker = invoker;
+        MethodType generalType = targetType.generic();
+        invoker = invoker1.asType(invokerType(generalType));
+        generalInvoker = invoker;
         return invoker;
     }
 
@@ -93,9 +93,9 @@
         if (invoker != null)  return invoker;
         MethodType erasedType = targetType.erase();
         if (erasedType == targetType.generic())
-            invoker = genericInvoker();
+            invoker = generalInvoker();
         else
-            invoker = MethodHandles.convertArguments(invoker1, invokerType(erasedType));
+            invoker = invoker1.asType(invokerType(erasedType));
         erasedInvoker = invoker;
         return invoker;
     }
@@ -103,7 +103,7 @@
     /*non-public*/ MethodHandle spreadInvoker(int objectArgCount) {
         MethodHandle vaInvoker = spreadInvokers[objectArgCount];
         if (vaInvoker != null)  return vaInvoker;
-        MethodHandle gInvoker = genericInvoker();
+        MethodHandle gInvoker = generalInvoker();
         vaInvoker = gInvoker.asSpreader(Object[].class, targetType.parameterCount() - objectArgCount);
         spreadInvokers[objectArgCount] = vaInvoker;
         return vaInvoker;
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java	Wed May 18 13:19:32 2011 +0200
@@ -525,7 +525,7 @@
     /** A factory type for resolving member names with the help of the VM.
      *  TBD: Define access-safe public constructors for this factory.
      */
-    public static class Factory {
+    /*non-public*/ static class Factory {
         private Factory() { } // singleton pattern
         static Factory INSTANCE = new Factory();
 
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java	Wed May 18 13:19:32 2011 +0200
@@ -26,6 +26,7 @@
 package java.lang.invoke;
 
 
+import sun.invoke.util.ValueConversions;
 import static java.lang.invoke.MethodHandleStatics.*;
 
 /**
@@ -53,12 +54,12 @@
  * and the kinds of transformations that apply to it.
  * <p>
  * A method handle contains a pair of special invoker methods
- * called {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.
+ * called {@link #invokeExact invokeExact} and {@link #invoke invoke}.
  * Both invoker methods provide direct access to the method handle's
  * underlying method, constructor, field, or other operation,
  * as modified by transformations of arguments and return values.
  * Both invokers accept calls which exactly match the method handle's own type.
- * The {@code invokeGeneric} invoker also accepts a range of other call types.
+ * The plain, inexact invoker also accepts a range of other call types.
  * <p>
  * Method handles are immutable and have no visible state.
  * Of course, they can be bound to underlying methods or data which exhibit state.
@@ -76,7 +77,7 @@
  * may change from time to time or across implementations from different vendors.
  *
  * <h3>Method handle compilation</h3>
- * A Java method call expression naming {@code invokeExact} or {@code invokeGeneric}
+ * A Java method call expression naming {@code invokeExact} or {@code invoke}
  * can invoke a method handle from Java source code.
  * From the viewpoint of source code, these methods can take any arguments
  * and their result can be cast to any return type.
@@ -86,7 +87,7 @@
  * which connects this freedom of invocation directly to the JVM execution stack.
  * <p>
  * As is usual with virtual methods, source-level calls to {@code invokeExact}
- * and {@code invokeGeneric} compile to an {@code invokevirtual} instruction.
+ * and {@code invoke} compile to an {@code invokevirtual} instruction.
  * More unusually, the compiler must record the actual argument types,
  * and may not perform method invocation conversions on the arguments.
  * Instead, it must push them on the stack according to their own unconverted types.
@@ -109,7 +110,7 @@
  * The first time a {@code invokevirtual} instruction is executed
  * it is linked, by symbolically resolving the names in the instruction
  * and verifying that the method call is statically legal.
- * This is true of calls to {@code invokeExact} and {@code invokeGeneric}.
+ * This is true of calls to {@code invokeExact} and {@code invoke}.
  * In this case, the type descriptor emitted by the compiler is checked for
  * correct syntax and names it contains are resolved.
  * Thus, an {@code invokevirtual} instruction which invokes
@@ -127,18 +128,18 @@
  * In the case of {@code invokeExact}, the type descriptor of the invocation
  * (after resolving symbolic type names) must exactly match the method type
  * of the receiving method handle.
- * In the case of {@code invokeGeneric}, the resolved type descriptor
+ * In the case of plain, inexact {@code invoke}, the resolved type descriptor
  * must be a valid argument to the receiver's {@link #asType asType} method.
- * Thus, {@code invokeGeneric} is more permissive than {@code invokeExact}.
+ * Thus, plain {@code invoke} is more permissive than {@code invokeExact}.
  * <p>
  * After type matching, a call to {@code invokeExact} directly
  * and immediately invoke the method handle's underlying method
  * (or other behavior, as the case may be).
  * <p>
- * A call to {@code invokeGeneric} works the same as a call to
+ * A call to plain {@code invoke} works the same as a call to
  * {@code invokeExact}, if the type descriptor specified by the caller
  * exactly matches the method handle's own type.
- * If there is a type mismatch, {@code invokeGeneric} attempts
+ * If there is a type mismatch, {@code invoke} attempts
  * to adjust the type of the receiving method handle,
  * as if by a call to {@link #asType asType},
  * to obtain an exactly invokable method handle {@code M2}.
@@ -152,7 +153,7 @@
  * In typical programs, method handle type matching will usually succeed.
  * But if a match fails, the JVM will throw a {@link WrongMethodTypeException},
  * either directly (in the case of {@code invokeExact}) or indirectly as if
- * by a failed call to {@code asType} (in the case of {@code invokeGeneric}).
+ * by a failed call to {@code asType} (in the case of {@code invoke}).
  * <p>
  * Thus, a method type mismatch which might show up as a linkage error
  * in a statically typed program can show up as
@@ -249,8 +250,8 @@
 mt = MethodType.methodType(java.util.List.class, Object[].class);
 mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
 assert(mh.isVarargsCollector());
-x = mh.invokeGeneric("one", "two");
-// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
+x = mh.invoke("one", "two");
+// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
 assert(x.equals(java.util.Arrays.asList("one","two")));
 // mt is (Object,Object,Object)Object
 mt = MethodType.genericMethodType(3);
@@ -269,12 +270,12 @@
 mh.invokeExact(System.out, "Hello, world.");
 // invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
  * </pre></blockquote>
- * Each of the above calls to {@code invokeExact} or {@code invokeGeneric}
+ * Each of the above calls to {@code invokeExact} or plain {@code invoke}
  * generates a single invokevirtual instruction with
  * the type descriptor indicated in the following comment.
  *
  * <h3>Exceptions</h3>
- * The methods {@code invokeExact} and {@code invokeGeneric} are declared
+ * The methods {@code invokeExact} and {@code invoke} are declared
  * to throw {@link java.lang.Throwable Throwable},
  * which is to say that there is no static restriction on what a method handle
  * can throw.  Since the JVM does not distinguish between checked
@@ -288,7 +289,7 @@
  *
  * <h3><a name="sigpoly"></a>Signature polymorphism</h3>
  * The unusual compilation and linkage behavior of
- * {@code invokeExact} and {@code invokeGeneric}
+ * {@code invokeExact} and plain {@code invoke}
  * is referenced by the term <em>signature polymorphism</em>.
  * A signature polymorphic method is one which can operate with
  * any of a wide range of call signatures and return types.
@@ -322,7 +323,7 @@
  * The following methods (and no others) are signature polymorphic:
  * <ul>
  * <li>{@link java.lang.invoke.MethodHandle#invokeExact   MethodHandle.invokeExact}
- * <li>{@link java.lang.invoke.MethodHandle#invokeGeneric MethodHandle.invokeGeneric}
+ * <li>{@link java.lang.invoke.MethodHandle#invoke        MethodHandle.invoke}
  * </ul>
  * <p>
  * A signature polymorphic method will be declared with the following properties:
@@ -374,24 +375,34 @@
  * <p>
  * As a special case,
  * when the Core Reflection API is used to view the signature polymorphic
- * methods {@code invokeExact} or {@code invokeGeneric} in this class,
- * they appear as single, non-polymorphic native methods.
- * Calls to these native methods do not result in method handle invocations.
+ * methods {@code invokeExact} or plain {@code invoke} in this class,
+ * they appear as ordinary non-polymorphic methods.
+ * Their reflective appearance, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * is unaffected by their special status in this API.
+ * For example, {@link java.lang.reflect.Method#getModifiers Method.getModifiers}
+ * will report exactly those modifier bits required for any similarly
+ * declared method, including in this case {@code native} and {@code varargs} bits.
+ * <p>
+ * As with any reflected method, these methods (when reflected) may be
+ * invoked via {@link java.lang.reflect.Method#invoke Method.invoke}.
+ * However, such reflective calls do not result in method handle invocations.
+ * Such a call, if passed the required argument
+ * (a single one, of type {@code Object[]}), will ignore the argument and
+ * will throw an {@code UnsupportedOperationException}.
+ * <p>
  * Since {@code invokevirtual} instructions can natively
  * invoke method handles under any type descriptor, this reflective view conflicts
- * with the normal presentation via bytecodes.
- * Thus, these two native methods, as viewed by
- * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
- * are placeholders only.
- * If invoked via {@link java.lang.reflect.Method#invoke Method.invoke},
- * they will throw {@code UnsupportedOperationException}.
+ * with the normal presentation of these methods via bytecodes.
+ * Thus, these two native methods, when reflectively viewed by
+ * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
  * <p>
  * In order to obtain an invoker method for a particular type descriptor,
  * use {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker},
- * or {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}.
+ * or {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}.
  * The {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
  * API is also able to return a method handle
- * to call {@code invokeExact} or {@code invokeGeneric},
+ * to call {@code invokeExact} or plain {@code invoke},
  * for any specified type descriptor .
  *
  * <h3>Interoperation between method handles and Java generics</h3>
@@ -523,7 +534,7 @@
      * adaptations directly on the caller's arguments,
      * and call the target method handle according to its own exact type.
      * <p>
-     * The type descriptor at the call site of {@code invokeGeneric} must
+     * The type descriptor at the call site of {@code invoke} must
      * be a valid argument to the receivers {@code asType} method.
      * In particular, the caller must specify the same argument arity
      * as the callee's type,
@@ -539,11 +550,18 @@
      * @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
      * @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
      */
+    public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
+
+    /**
+     * <em>Temporary alias</em> for {@link #invoke}, for backward compatibility with some versions of JSR 292.
+     * On some JVMs, support can be excluded by the flags {@code -XX:+UnlockExperimentalVMOptions -XX:-AllowInvokeGeneric}.
+     * @deprecated Will be removed for JSR 292 Proposed Final Draft.
+     */
     public final native @PolymorphicSignature Object invokeGeneric(Object... args) throws Throwable;
 
     /**
      * Performs a varargs invocation, passing the arguments in the given array
-     * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
+     * 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.
      * <p>
@@ -553,7 +571,7 @@
      * <ul>
      * <li>Determine the length of the argument array as {@code N}.
      *     For a null reference, {@code N=0}. </li>
-     * <li>Determine the generic type {@code TN} of {@code N} arguments as
+     * <li>Determine the general type {@code TN} of {@code N} arguments as
      *     as {@code TN=MethodType.genericMethodType(N)}.</li>
      * <li>Force the original target method handle {@code MH0} to the
      *     required type, as {@code MH1 = MH0.asType(TN)}. </li>
@@ -580,7 +598,7 @@
      * Object result = invoker.invokeExact(this, arguments);
      * </pre></blockquote>
      * <p>
-     * Unlike the signature polymorphic methods {@code invokeExact} and {@code invokeGeneric},
+     * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke},
      * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI.
      * It can therefore be used as a bridge between native or reflective code and method handles.
      *
@@ -595,11 +613,11 @@
         int argc = arguments == null ? 0 : arguments.length;
         MethodType type = type();
         if (type.parameterCount() != argc) {
-            // simulate invokeGeneric
+            // simulate invoke
             return asType(MethodType.genericMethodType(argc)).invokeWithArguments(arguments);
         }
         if (argc <= 10) {
-            MethodHandle invoker = type.invokers().genericInvoker();
+            MethodHandle invoker = type.invokers().generalInvoker();
             switch (argc) {
                 case 0:  return invoker.invokeExact(this);
                 case 1:  return invoker.invokeExact(this,
@@ -644,7 +662,7 @@
 
     /**
      * Performs a varargs invocation, passing the arguments in the given array
-     * to the method handle, as if via {@link #invokeGeneric invokeGeneric} from a call site
+     * 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.
      * <p>
@@ -672,9 +690,9 @@
      * If the original type and new type are equal, returns {@code this}.
      * <p>
      * This method provides the crucial behavioral difference between
-     * {@link #invokeExact invokeExact} and {@link #invokeGeneric invokeGeneric}.  The two methods
+     * {@link #invokeExact invokeExact} and plain, inexact {@link #invoke invoke}.  The two methods
      * perform the same steps when the caller's type descriptor is identical
-     * with the callee's, but when the types differ, {@link #invokeGeneric invokeGeneric}
+     * with the callee's, but when the types differ, plain {@link #invoke invoke}
      * also calls {@code asType} (or some internal equivalent) in order
      * to match up the caller's and callee's types.
      * <p>
@@ -689,6 +707,9 @@
      * @see MethodHandles#convertArguments
      */
     public MethodHandle asType(MethodType newType) {
+        if (!type.isConvertibleTo(newType)) {
+            throw new WrongMethodTypeException("cannot convert "+type+" to "+newType);
+        }
         return MethodHandles.convertArguments(this, newType);
     }
 
@@ -731,13 +752,9 @@
     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
         Class<?> arrayElement = arrayType.getComponentType();
         if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
-        MethodType oldType = type();
-        int nargs = oldType.parameterCount();
+        int nargs = type().parameterCount();
         if (nargs < arrayLength)  throw newIllegalArgumentException("bad spread array length");
-        int keepPosArgs = nargs - arrayLength;
-        MethodType newType = oldType.dropParameterTypes(keepPosArgs, nargs);
-        newType = newType.insertParameterTypes(keepPosArgs, arrayType);
-        return MethodHandles.spreadArguments(this, newType);
+        return MethodHandleImpl.spreadArguments(this, arrayType, arrayLength);
     }
 
     /**
@@ -780,15 +797,18 @@
      * @see #asVarargsCollector
      */
     public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
+        asCollectorChecks(arrayType, arrayLength);
+        MethodHandle collector = ValueConversions.varargsArray(arrayType, arrayLength);
+        return MethodHandleImpl.collectArguments(this, type.parameterCount()-1, collector);
+    }
+
+    private  void asCollectorChecks(Class<?> arrayType, int arrayLength) {
         Class<?> arrayElement = arrayType.getComponentType();
-        if (arrayElement == null)  throw newIllegalArgumentException("not an array type");
-        MethodType oldType = type();
-        int nargs = oldType.parameterCount();
-        if (nargs == 0)  throw newIllegalArgumentException("no trailing argument");
-        MethodType newType = oldType.dropParameterTypes(nargs-1, nargs);
-        newType = newType.insertParameterTypes(nargs-1,
-                    java.util.Collections.<Class<?>>nCopies(arrayLength, arrayElement));
-        return MethodHandles.collectArguments(this, newType);
+        if (arrayElement == null)
+            throw newIllegalArgumentException("not an array type", arrayType);
+        int nargs = type().parameterCount();
+        if (nargs == 0 || !type().parameterType(nargs-1).isAssignableFrom(arrayType))
+            throw newIllegalArgumentException("array type not assignable to trailing argument", this, arrayType);
     }
 
     /**
@@ -798,7 +818,7 @@
      * <p>
      * The type and behavior of the adapter will be the same as
      * the type and behavior of the target, except that certain
-     * {@code invokeGeneric} and {@code asType} requests can lead to
+     * {@code invoke} and {@code asType} requests can lead to
      * trailing positional arguments being collected into target's
      * trailing parameter.
      * Also, the last parameter type of the adapter will be
@@ -812,17 +832,17 @@
      * since it accepts a whole array of indeterminate length,
      * rather than a fixed number of arguments.)
      * <p>
-     * When called with {@link #invokeGeneric invokeGeneric}, if the caller
+     * When called with plain, inexact {@link #invoke invoke}, if the caller
      * type is the same as the adapter, the adapter invokes the target as with
      * {@code invokeExact}.
-     * (This is the normal behavior for {@code invokeGeneric} when types match.)
+     * (This is the normal behavior for {@code invoke} when types match.)
      * <p>
      * Otherwise, if the caller and adapter arity are the same, and the
      * trailing parameter type of the caller is a reference type identical to
      * or assignable to the trailing parameter type of the adapter,
      * the arguments and return values are converted pairwise,
      * as if by {@link MethodHandles#convertArguments convertArguments}.
-     * (This is also normal behavior for {@code invokeGeneric} in such a case.)
+     * (This is also normal behavior for {@code invoke} in such a case.)
      * <p>
      * Otherwise, the arities differ, or the adapter's trailing parameter
      * type is not assignable from the corresponding caller type.
@@ -838,7 +858,7 @@
      * where {@code N} is the arity of the target.
      * Also, there must exist conversions from the incoming arguments
      * to the target's arguments.
-     * As with other uses of {@code invokeGeneric}, if these basic
+     * As with other uses of plain {@code invoke}, if these basic
      * requirements are not fulfilled, a {@code WrongMethodTypeException}
      * may be thrown.
      * <p>
@@ -856,7 +876,7 @@
      * <p>
      * The behavior of {@link #asType asType} is also specialized for
      * variable arity adapters, to maintain the invariant that
-     * {@code invokeGeneric} is always equivalent to an {@code asType}
+     * plain, inexact {@code invoke} is always equivalent to an {@code asType}
      * call to adjust the target type, followed by {@code invokeExact}.
      * Therefore, a variable arity adapter responds
      * to an {@code asType} request by building a fixed arity collector,
@@ -893,12 +913,12 @@
 MethodHandle asList = publicLookup()
   .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
   .asVarargsCollector(Object[].class);
-assertEquals("[]", asList.invokeGeneric().toString());
-assertEquals("[1]", asList.invokeGeneric(1).toString());
-assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString());
+assertEquals("[]", asList.invoke().toString());
+assertEquals("[1]", asList.invoke(1).toString());
+assertEquals("[two, too]", asList.invoke("two", "too").toString());
 Object[] argv = { "three", "thee", "tee" };
-assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString());
-List ls = (List) asList.invokeGeneric((Object)argv);
+assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
+List ls = (List) asList.invoke((Object)argv);
 assertEquals(1, ls.size());
 assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
      * </pre></blockquote>
@@ -926,9 +946,9 @@
   .asVarargsCollector(Object[].class);
 MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh);
 assert(vamh.type().equals(mh.type()));
-assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString());
+assertEquals("[1, 2, 3]", vamh.invoke(1,2,3).toString());
 boolean failed = false;
-try { mh.invokeGeneric(1,2,3); }
+try { mh.invoke(1,2,3); }
 catch (WrongMethodTypeException ex) { failed = true; }
 assert(failed);
      * </pre></blockquote>
@@ -960,7 +980,7 @@
      * <li>an {@code ldc} instruction of a {@code CONSTANT_MethodHandle}
      *     which resolves to a variable arity Java method or constructor
      * </ul>
-     * @return true if this method handle accepts more than one arity of {@code invokeGeneric} calls
+     * @return true if this method handle accepts more than one arity of plain, inexact {@code invoke} calls
      * @see #asVarargsCollector
      */
     public boolean isVarargsCollector() {
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -121,11 +121,11 @@
             if (nargs < INVOKES.length) {
                 MethodHandle invoke = INVOKES[nargs];
                 MethodType conType = CON_TYPES[nargs];
-                MethodHandle gcon = convertArguments(rawConstructor, conType, rawConType, null);
+                MethodHandle gcon = convertArguments(rawConstructor, conType, rawConType, 0);
                 if (gcon == null)  return null;
                 MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
                 assert(galloc.type() == newType.generic());
-                return convertArguments(galloc, newType, galloc.type(), null);
+                return convertArguments(galloc, newType, galloc.type(), 0);
             } else {
                 MethodHandle invoke = VARARGS_INVOKE;
                 MethodType conType = CON_TYPES[nargs];
@@ -256,8 +256,8 @@
                 FieldAccessor.ahandle(arrayClass, true)
             };
             if (mhs[0].type().parameterType(0) == Class.class) {
-                mhs[0] = MethodHandles.insertArguments(mhs[0], 0, elemClass);
-                mhs[1] = MethodHandles.insertArguments(mhs[1], 0, elemClass);
+                mhs[0] = mhs[0].bindTo(elemClass);
+                mhs[1] = mhs[1].bindTo(elemClass);
             }
             synchronized (FieldAccessor.ARRAY_CACHE) {}  // memory barrier
             FieldAccessor.ARRAY_CACHE.put(elemClass, mhs);
@@ -372,7 +372,7 @@
             if (evclass != vclass || (!isStatic && ecclass != cclass)) {
                 MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
                 strongType = strongType.insertParameterTypes(0, FieldAccessor.class);
-                mh = MethodHandles.convertArguments(mh, strongType);
+                mh = convertArguments(mh, strongType, 0);
             }
             return mh;
         }
@@ -439,8 +439,8 @@
             }
             if (caclass != null) {
                 MethodType strongType = FieldAccessor.atype(caclass, isSetter);
-                mh = MethodHandles.insertArguments(mh, 0, caclass);
-                mh = MethodHandles.convertArguments(mh, strongType);
+                mh = mh.bindTo(caclass);
+                mh = convertArguments(mh, strongType, 0);
             }
             return mh;
         }
@@ -465,7 +465,7 @@
                     dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) {
                     MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0);
                     MethodType newType = target.type().dropParameterTypes(0, 1);
-                    return convertArguments(bmh, newType, bmh.type(), null);
+                    return convertArguments(bmh, newType, bmh.type(), 0);
                 }
             }
         }
@@ -486,301 +486,378 @@
         return new BoundMethodHandle(target, receiver, argnum);
     }
 
-    static MethodHandle convertArguments(MethodHandle target,
+    static MethodHandle permuteArguments(MethodHandle target,
                                                 MethodType newType,
                                                 MethodType oldType,
                                                 int[] permutationOrNull) {
         assert(oldType.parameterCount() == target.type().parameterCount());
-        if (permutationOrNull != null) {
-            int outargs = oldType.parameterCount(), inargs = newType.parameterCount();
-            if (permutationOrNull.length != outargs)
-                throw newIllegalArgumentException("wrong number of arguments in permutation");
-            // Make the individual outgoing argument types match up first.
-            Class<?>[] callTypeArgs = new Class<?>[outargs];
-            for (int i = 0; i < outargs; i++)
-                callTypeArgs[i] = newType.parameterType(permutationOrNull[i]);
-            MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs);
-            target = convertArguments(target, callType, oldType, null);
-            assert(target != null);
-            oldType = target.type();
-            List<Integer> goal = new ArrayList<Integer>();  // i*TOKEN
-            List<Integer> state = new ArrayList<Integer>(); // i*TOKEN
-            List<Integer> drops = new ArrayList<Integer>(); // not tokens
-            List<Integer> dups = new ArrayList<Integer>();  // not tokens
-            final int TOKEN = 10; // to mark items which are symbolic only
-            // state represents the argument values coming into target
-            for (int i = 0; i < outargs; i++) {
-                state.add(permutationOrNull[i] * TOKEN);
+        int outargs = oldType.parameterCount(), inargs = newType.parameterCount();
+        if (permutationOrNull.length != outargs)
+            throw newIllegalArgumentException("wrong number of arguments in permutation");
+        // Make the individual outgoing argument types match up first.
+        Class<?>[] callTypeArgs = new Class<?>[outargs];
+        for (int i = 0; i < outargs; i++)
+            callTypeArgs[i] = newType.parameterType(permutationOrNull[i]);
+        MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs);
+        target = convertArguments(target, callType, oldType, 0);
+        assert(target != null);
+        oldType = target.type();
+        List<Integer> goal = new ArrayList<Integer>();  // i*TOKEN
+        List<Integer> state = new ArrayList<Integer>(); // i*TOKEN
+        List<Integer> drops = new ArrayList<Integer>(); // not tokens
+        List<Integer> dups = new ArrayList<Integer>();  // not tokens
+        final int TOKEN = 10; // to mark items which are symbolic only
+        // state represents the argument values coming into target
+        for (int i = 0; i < outargs; i++) {
+            state.add(permutationOrNull[i] * TOKEN);
+        }
+        // goal represents the desired state
+        for (int i = 0; i < inargs; i++) {
+            if (state.contains(i * TOKEN)) {
+                goal.add(i * TOKEN);
+            } else {
+                // adapter must initially drop all unused arguments
+                drops.add(i);
             }
-            // goal represents the desired state
-            for (int i = 0; i < inargs; i++) {
-                if (state.contains(i * TOKEN)) {
-                    goal.add(i * TOKEN);
-                } else {
-                    // adapter must initially drop all unused arguments
-                    drops.add(i);
+        }
+        // detect duplications
+        while (state.size() > goal.size()) {
+            for (int i2 = 0; i2 < state.size(); i2++) {
+                int arg1 = state.get(i2);
+                int i1 = state.indexOf(arg1);
+                if (i1 != i2) {
+                    // found duplicate occurrence at i2
+                    int arg2 = (inargs++) * TOKEN;
+                    state.set(i2, arg2);
+                    dups.add(goal.indexOf(arg1));
+                    goal.add(arg2);
                 }
             }
-            // detect duplications
-            while (state.size() > goal.size()) {
-                for (int i2 = 0; i2 < state.size(); i2++) {
-                    int arg1 = state.get(i2);
-                    int i1 = state.indexOf(arg1);
-                    if (i1 != i2) {
-                        // found duplicate occurrence at i2
-                        int arg2 = (inargs++) * TOKEN;
-                        state.set(i2, arg2);
-                        dups.add(goal.indexOf(arg1));
-                        goal.add(arg2);
+        }
+        assert(state.size() == goal.size());
+        int size = goal.size();
+        while (!state.equals(goal)) {
+            // Look for a maximal sequence of adjacent misplaced arguments,
+            // and try to rotate them into place.
+            int bestRotArg = -10 * TOKEN, bestRotLen = 0;
+            int thisRotArg = -10 * TOKEN, thisRotLen = 0;
+            for (int i = 0; i < size; i++) {
+                int arg = state.get(i);
+                // Does this argument match the current run?
+                if (arg == thisRotArg + TOKEN) {
+                    thisRotArg = arg;
+                    thisRotLen += 1;
+                    if (bestRotLen < thisRotLen) {
+                        bestRotLen = thisRotLen;
+                        bestRotArg = thisRotArg;
+                    }
+                } else {
+                    // The old sequence (if any) stops here.
+                    thisRotLen = 0;
+                    thisRotArg = -10 * TOKEN;
+                    // But maybe a new one starts here also.
+                    int wantArg = goal.get(i);
+                    final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION;
+                    if (arg != wantArg &&
+                        arg >= wantArg - TOKEN * MAX_ARG_ROTATION &&
+                        arg <= wantArg + TOKEN * MAX_ARG_ROTATION) {
+                        thisRotArg = arg;
+                        thisRotLen = 1;
                     }
                 }
             }
-            assert(state.size() == goal.size());
-            int size = goal.size();
-            while (!state.equals(goal)) {
-                // Look for a maximal sequence of adjacent misplaced arguments,
-                // and try to rotate them into place.
-                int bestRotArg = -10 * TOKEN, bestRotLen = 0;
-                int thisRotArg = -10 * TOKEN, thisRotLen = 0;
-                for (int i = 0; i < size; i++) {
-                    int arg = state.get(i);
-                    // Does this argument match the current run?
-                    if (arg == thisRotArg + TOKEN) {
-                        thisRotArg = arg;
-                        thisRotLen += 1;
-                        if (bestRotLen < thisRotLen) {
-                            bestRotLen = thisRotLen;
-                            bestRotArg = thisRotArg;
-                        }
-                    } else {
-                        // The old sequence (if any) stops here.
-                        thisRotLen = 0;
-                        thisRotArg = -10 * TOKEN;
-                        // But maybe a new one starts here also.
-                        int wantArg = goal.get(i);
-                        final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION;
-                        if (arg != wantArg &&
-                            arg >= wantArg - TOKEN * MAX_ARG_ROTATION &&
-                            arg <= wantArg + TOKEN * MAX_ARG_ROTATION) {
-                            thisRotArg = arg;
-                            thisRotLen = 1;
-                        }
+            if (bestRotLen >= 2) {
+                // Do a rotation if it can improve argument positioning
+                // by at least 2 arguments.  This is not always optimal,
+                // but it seems to catch common cases.
+                int dstEnd = state.indexOf(bestRotArg);
+                int srcEnd = goal.indexOf(bestRotArg);
+                int rotBy = dstEnd - srcEnd;
+                int dstBeg = dstEnd - (bestRotLen - 1);
+                int srcBeg = srcEnd - (bestRotLen - 1);
+                assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs
+                // Make a span which covers both source and destination.
+                int rotBeg = Math.min(dstBeg, srcBeg);
+                int rotEnd = Math.max(dstEnd, srcEnd);
+                int score = 0;
+                for (int i = rotBeg; i <= rotEnd; i++) {
+                    if ((int)state.get(i) != (int)goal.get(i))
+                        score += 1;
+                }
+                List<Integer> rotSpan = state.subList(rotBeg, rotEnd+1);
+                Collections.rotate(rotSpan, -rotBy);  // reverse direction
+                for (int i = rotBeg; i <= rotEnd; i++) {
+                    if ((int)state.get(i) != (int)goal.get(i))
+                        score -= 1;
+                }
+                if (score >= 2) {
+                    // Improved at least two argument positions.  Do it.
+                    List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
+                    Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
+                    MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes);
+                    MethodHandle nextTarget
+                            = AdapterMethodHandle.makeRotateArguments(rotType, target,
+                                    rotBeg, rotSpan.size(), rotBy);
+                    if (nextTarget != null) {
+                        //System.out.println("Rot: "+rotSpan+" by "+rotBy);
+                        target = nextTarget;
+                        oldType = rotType;
+                        continue;
                     }
                 }
-                if (bestRotLen >= 2) {
-                    // Do a rotation if it can improve argument positioning
-                    // by at least 2 arguments.  This is not always optimal,
-                    // but it seems to catch common cases.
-                    int dstEnd = state.indexOf(bestRotArg);
-                    int srcEnd = goal.indexOf(bestRotArg);
-                    int rotBy = dstEnd - srcEnd;
-                    int dstBeg = dstEnd - (bestRotLen - 1);
-                    int srcBeg = srcEnd - (bestRotLen - 1);
-                    assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs
-                    // Make a span which covers both source and destination.
-                    int rotBeg = Math.min(dstBeg, srcBeg);
-                    int rotEnd = Math.max(dstEnd, srcEnd);
-                    int score = 0;
-                    for (int i = rotBeg; i <= rotEnd; i++) {
-                        if ((int)state.get(i) != (int)goal.get(i))
-                            score += 1;
-                    }
-                    List<Integer> rotSpan = state.subList(rotBeg, rotEnd+1);
-                    Collections.rotate(rotSpan, -rotBy);  // reverse direction
-                    for (int i = rotBeg; i <= rotEnd; i++) {
-                        if ((int)state.get(i) != (int)goal.get(i))
-                            score -= 1;
-                    }
-                    if (score >= 2) {
-                        // Improved at least two argument positions.  Do it.
-                        List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
-                        Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
-                        MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes);
-                        MethodHandle nextTarget
-                                = AdapterMethodHandle.makeRotateArguments(rotType, target,
-                                        rotBeg, rotSpan.size(), rotBy);
-                        if (nextTarget != null) {
-                            //System.out.println("Rot: "+rotSpan+" by "+rotBy);
-                            target = nextTarget;
-                            oldType = rotType;
-                            continue;
-                        }
-                    }
-                    // Else de-rotate, and drop through to the swap-fest.
-                    Collections.rotate(rotSpan, rotBy);
-                }
+                // Else de-rotate, and drop through to the swap-fest.
+                Collections.rotate(rotSpan, rotBy);
+            }
 
-                // Now swap like the wind!
-                List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
-                for (int i = 0; i < size; i++) {
-                    // What argument do I want here?
-                    int arg = goal.get(i);
-                    if (arg != state.get(i)) {
-                        // Where is it now?
-                        int j = state.indexOf(arg);
-                        Collections.swap(ptypes, i, j);
-                        MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes);
-                        target = AdapterMethodHandle.makeSwapArguments(swapType, target, i, j);
-                        if (target == null)  throw newIllegalArgumentException("cannot swap");
-                        assert(target.type() == swapType);
-                        oldType = swapType;
-                        Collections.swap(state, i, j);
-                    }
+            // Now swap like the wind!
+            List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
+            for (int i = 0; i < size; i++) {
+                // What argument do I want here?
+                int arg = goal.get(i);
+                if (arg != state.get(i)) {
+                    // Where is it now?
+                    int j = state.indexOf(arg);
+                    Collections.swap(ptypes, i, j);
+                    MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes);
+                    target = AdapterMethodHandle.makeSwapArguments(swapType, target, i, j);
+                    if (target == null)  throw newIllegalArgumentException("cannot swap");
+                    assert(target.type() == swapType);
+                    oldType = swapType;
+                    Collections.swap(state, i, j);
                 }
-                // One pass of swapping must finish the job.
-                assert(state.equals(goal));
+            }
+            // One pass of swapping must finish the job.
+            assert(state.equals(goal));
+        }
+        while (!dups.isEmpty()) {
+            // Grab a contiguous trailing sequence of dups.
+            int grab = dups.size() - 1;
+            int dupArgPos = dups.get(grab), dupArgCount = 1;
+            while (grab - 1 >= 0) {
+                int dup0 = dups.get(grab - 1);
+                if (dup0 != dupArgPos - 1)  break;
+                dupArgPos -= 1;
+                dupArgCount += 1;
+                grab -= 1;
+            }
+            //if (dupArgCount > 1)  System.out.println("Dup: "+dups.subList(grab, dups.size()));
+            dups.subList(grab, dups.size()).clear();
+            // In the new target type drop that many args from the tail:
+            List<Class<?>> ptypes = oldType.parameterList();
+            ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
+            MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes);
+            target = AdapterMethodHandle.makeDupArguments(dupType, target, dupArgPos, dupArgCount);
+            if (target == null)
+                throw newIllegalArgumentException("cannot dup");
+            oldType = target.type();
+        }
+        while (!drops.isEmpty()) {
+            // Grab a contiguous initial sequence of drops.
+            int dropArgPos = drops.get(0), dropArgCount = 1;
+            while (dropArgCount < drops.size()) {
+                int drop1 = drops.get(dropArgCount);
+                if (drop1 != dropArgPos + dropArgCount)  break;
+                dropArgCount += 1;
             }
-            while (!dups.isEmpty()) {
-                // Grab a contiguous trailing sequence of dups.
-                int grab = dups.size() - 1;
-                int dupArgPos = dups.get(grab), dupArgCount = 1;
-                while (grab - 1 >= 0) {
-                    int dup0 = dups.get(grab - 1);
-                    if (dup0 != dupArgPos - 1)  break;
-                    dupArgPos -= 1;
-                    dupArgCount += 1;
-                    grab -= 1;
-                }
-                //if (dupArgCount > 1)  System.out.println("Dup: "+dups.subList(grab, dups.size()));
-                dups.subList(grab, dups.size()).clear();
-                // In the new target type drop that many args from the tail:
-                List<Class<?>> ptypes = oldType.parameterList();
-                ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
-                MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes);
-                target = AdapterMethodHandle.makeDupArguments(dupType, target, dupArgPos, dupArgCount);
-                if (target == null)
-                    throw newIllegalArgumentException("cannot dup");
-                oldType = target.type();
+            //if (dropArgCount > 1)  System.out.println("Drop: "+drops.subList(0, dropArgCount));
+            drops.subList(0, dropArgCount).clear();
+            List<Class<?>> dropTypes = newType.parameterList()
+                    .subList(dropArgPos, dropArgPos + dropArgCount);
+            MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes);
+            target = AdapterMethodHandle.makeDropArguments(dropType, target, dropArgPos, dropArgCount);
+            if (target == null)  throw newIllegalArgumentException("cannot drop");
+            oldType = target.type();
+        }
+        return convertArguments(target, newType, oldType, 0);
+    }
+
+    /*non-public*/ static
+    MethodHandle convertArguments(MethodHandle target, MethodType newType, int level) {
+        MethodType oldType = target.type();
+        if (oldType.equals(newType))
+            return target;
+        assert(level > 1 || oldType.isConvertibleTo(newType));
+        MethodHandle retFilter = null;
+        Class<?> oldRT = oldType.returnType();
+        Class<?> newRT = newType.returnType();
+        if (!VerifyType.isNullConversion(oldRT, newRT)) {
+            if (oldRT == void.class) {
+                Wrapper wrap = newRT.isPrimitive() ? Wrapper.forPrimitiveType(newRT) : Wrapper.OBJECT;
+                retFilter = ValueConversions.zeroConstantFunction(wrap);
+            } else {
+                retFilter = MethodHandles.identity(newRT);
+                retFilter = convertArguments(retFilter, retFilter.type().changeParameterType(0, oldRT), level);
             }
-            while (!drops.isEmpty()) {
-                // Grab a contiguous initial sequence of drops.
-                int dropArgPos = drops.get(0), dropArgCount = 1;
-                while (dropArgCount < drops.size()) {
-                    int drop1 = drops.get(dropArgCount);
-                    if (drop1 != dropArgPos + dropArgCount)  break;
-                    dropArgCount += 1;
-                }
-                //if (dropArgCount > 1)  System.out.println("Drop: "+drops.subList(0, dropArgCount));
-                drops.subList(0, dropArgCount).clear();
-                List<Class<?>> dropTypes = newType.parameterList()
-                        .subList(dropArgPos, dropArgPos + dropArgCount);
-                MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes);
-                target = AdapterMethodHandle.makeDropArguments(dropType, target, dropArgPos, dropArgCount);
-                if (target == null)  throw newIllegalArgumentException("cannot drop");
-                oldType = target.type();
-            }
+            newType = newType.changeReturnType(oldRT);
+        }
+        MethodHandle res = null;
+        Exception ex = null;
+        try {
+            res = convertArguments(target, newType, oldType, level);
+        } catch (IllegalArgumentException ex1) {
+            ex = ex1;
         }
+        if (res == null) {
+            WrongMethodTypeException wmt = new WrongMethodTypeException("cannot convert to "+newType+": "+target);
+            wmt.initCause(ex);
+            throw wmt;
+        }
+        if (retFilter != null)
+            res = MethodHandles.filterReturnValue(res, retFilter);
+        return res;
+    }
+
+    static MethodHandle convertArguments(MethodHandle target,
+                                                MethodType newType,
+                                                MethodType oldType,
+                                                int level) {
+        assert(oldType.parameterCount() == target.type().parameterCount());
         if (newType == oldType)
             return target;
         if (oldType.parameterCount() != newType.parameterCount())
-            throw newIllegalArgumentException("mismatched parameter count");
-        MethodHandle res = AdapterMethodHandle.makePairwiseConvert(newType, target);
+            throw newIllegalArgumentException("mismatched parameter count", oldType, newType);
+        MethodHandle res = AdapterMethodHandle.makePairwiseConvert(newType, target, level);
         if (res != null)
             return res;
+        // We can come here in the case of target(int)void => (Object)void,
+        // because the unboxing logic for Object => int is complex.
         int argc = oldType.parameterCount();
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
         // The JVM can't do it directly, so fill in the gap with a Java adapter.
         // TO DO: figure out what to put here from case-by-case experience
         // Use a heavier method:  Convert all the arguments to Object,
         // then back to the desired types.  We might have to use Java-based
         // method handles to do this.
         MethodType objType = MethodType.genericMethodType(argc);
-        MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(objType, target);
+        MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(objType, target, level);
         if (objTarget == null)
             objTarget = FromGeneric.make(target);
-        res = AdapterMethodHandle.makePairwiseConvert(newType, objTarget);
+        res = AdapterMethodHandle.makePairwiseConvert(newType, objTarget, level);
         if (res != null)
             return res;
         return ToGeneric.make(newType, objTarget);
     }
 
+    static MethodHandle spreadArguments(MethodHandle target, Class<?> arrayType, int arrayLength) {
+        MethodType oldType = target.type();
+        int nargs = oldType.parameterCount();
+        int keepPosArgs = nargs - arrayLength;
+        MethodType newType = oldType
+                .dropParameterTypes(keepPosArgs, nargs)
+                .insertParameterTypes(keepPosArgs, arrayType);
+        return spreadArguments(target, newType, keepPosArgs, arrayType, arrayLength);
+    }
+    static MethodHandle spreadArguments(MethodHandle target, MethodType newType, int spreadArgPos) {
+        int arrayLength = target.type().parameterCount() - spreadArgPos;
+        return spreadArguments(target, newType, spreadArgPos, Object[].class, arrayLength);
+    }
     static MethodHandle spreadArguments(MethodHandle target,
                                                MethodType newType,
-                                               int spreadArg) {
+                                               int spreadArgPos,
+                                               Class<?> arrayType,
+                                               int arrayLength) {
         // TO DO: maybe allow the restarg to be Object and implicitly cast to Object[]
         MethodType oldType = target.type();
         // spread the last argument of newType to oldType
-        int spreadCount = oldType.parameterCount() - spreadArg;
-        Class<Object[]> spreadArgType = Object[].class;
-        MethodHandle res = AdapterMethodHandle.makeSpreadArguments(newType, target, spreadArgType, spreadArg, spreadCount);
-        if (res != null)
-            return res;
-        // try an intermediate adapter
-        Class<?> spreadType = null;
-        if (spreadArg < 0 || spreadArg >= newType.parameterCount()
-            || !VerifyType.isSpreadArgType(spreadType = newType.parameterType(spreadArg)))
-            throw newIllegalArgumentException("no restarg in "+newType);
-        Class<?>[] ptypes = oldType.parameterArray();
-        for (int i = 0; i < spreadCount; i++)
-            ptypes[spreadArg + i] = VerifyType.spreadArgElementType(spreadType, i);
-        MethodType midType = MethodType.methodType(newType.returnType(), ptypes);
-        // after spreading, some arguments may need further conversion
-        MethodHandle target2 = convertArguments(target, midType, oldType, null);
-        if (target2 == null)
-            throw new UnsupportedOperationException("NYI: convert "+midType+" =calls=> "+oldType);
-        res = AdapterMethodHandle.makeSpreadArguments(newType, target2, spreadArgType, spreadArg, spreadCount);
-        if (res != null)
-            return res;
-        res = SpreadGeneric.make(target2, spreadCount);
-        if (res != null)
-            res = convertArguments(res, newType, res.type(), null);
+        assert(arrayLength == oldType.parameterCount() - spreadArgPos);
+        assert(newType.parameterType(spreadArgPos) == arrayType);
+        MethodHandle res = AdapterMethodHandle.makeSpreadArguments(newType, target, arrayType, spreadArgPos, arrayLength);
+        if (res == null)  throw new IllegalArgumentException("spread on "+target+" with "+arrayType.getSimpleName());
         return res;
     }
 
     static MethodHandle collectArguments(MethodHandle target,
+                                                int collectArg,
+                                                MethodHandle collector) {
+        MethodType type = target.type();
+        Class<?> collectType = collector.type().returnType();
+        if (collectType != type.parameterType(collectArg))
+            target = target.asType(type.changeParameterType(collectArg, collectType));
+        MethodType newType = type
+                .dropParameterTypes(collectArg, collectArg+1)
+                .insertParameterTypes(collectArg, collector.type().parameterArray());
+        return collectArguments(target, newType, collectArg, collector);
+    }
+    static MethodHandle collectArguments(MethodHandle target,
                                                 MethodType newType,
                                                 int collectArg,
                                                 MethodHandle collector) {
         MethodType oldType = target.type();     // (a...,c)=>r
-        if (collector == null) {
-            int numCollect = newType.parameterCount() - oldType.parameterCount() + 1;
-            collector = ValueConversions.varargsArray(numCollect);
-        }
         //         newType                      // (a..., b...)=>r
         MethodType colType = collector.type();  // (b...)=>c
         //         oldType                      // (a..., b...)=>r
         assert(newType.parameterCount() == collectArg + colType.parameterCount());
         assert(oldType.parameterCount() == collectArg + 1);
-        MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null);
-        MethodHandle gcollector = convertArguments(collector, colType.generic(), colType, null);
-        if (gtarget == null || gcollector == null)  return null;
-        MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget);
-        MethodHandle result = convertArguments(gresult, newType, gresult.type(), null);
+        MethodHandle result = null;
+        if (AdapterMethodHandle.canCollectArguments(oldType, colType, collectArg, false)) {
+            result = AdapterMethodHandle.makeCollectArguments(target, collector, collectArg, false);
+        }
+        if (result == null) {
+            assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
+            MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, 0);
+            MethodHandle gcollector = convertArguments(collector, colType.generic(), colType, 0);
+            if (gtarget == null || gcollector == null)  return null;
+            MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget);
+            result = convertArguments(gresult, newType, gresult.type(), 0);
+        }
         return result;
     }
 
     static MethodHandle filterArgument(MethodHandle target,
-                                              int pos,
-                                              MethodHandle filter) {
-        MethodType ttype = target.type(), gttype = ttype.generic();
+                                       int pos,
+                                       MethodHandle filter) {
+        MethodType ttype = target.type();
+        MethodType ftype = filter.type();
+        assert(ftype.parameterCount() == 1);
+        MethodType rtype = ttype.changeParameterType(pos, ftype.parameterType(0));
+        MethodType gttype = ttype.generic();
         if (ttype != gttype) {
-            target = convertArguments(target, gttype, ttype, null);
+            target = convertArguments(target, gttype, ttype, 0);
             ttype = gttype;
         }
-        MethodType ftype = filter.type(), gftype = ftype.generic();
-        if (ftype.parameterCount() != 1)
-            throw new InternalError();
+        MethodType gftype = ftype.generic();
         if (ftype != gftype) {
-            filter = convertArguments(filter, gftype, ftype, null);
+            filter = convertArguments(filter, gftype, ftype, 0);
             ftype = gftype;
         }
-        if (ftype == ttype) {
+        MethodHandle result = null;
+        if (AdapterMethodHandle.canCollectArguments(ttype, ftype, pos, false)) {
+            result = AdapterMethodHandle.makeCollectArguments(target, filter, pos, false);
+        }
+        if (result == null) {
+            assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
+            if (ftype == ttype) {
             // simple unary case
-            return FilterOneArgument.make(filter, target);
+                result = FilterOneArgument.make(filter, target);
+            } else {
+                result = FilterGeneric.makeArgumentFilter(pos, filter, target);
+            }
         }
-        return FilterGeneric.makeArgumentFilter(pos, filter, target);
+        if (result.type() != rtype)
+            result = result.asType(rtype);
+        return result;
     }
 
     static MethodHandle foldArguments(MethodHandle target,
-                                             MethodType newType,
-                                             MethodHandle combiner) {
+                                      MethodType newType,
+                                      int foldPos,
+                                      MethodHandle combiner) {
         MethodType oldType = target.type();
         MethodType ctype = combiner.type();
-        MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, null);
-        MethodHandle gcombiner = convertArguments(combiner, ctype.generic(), ctype, null);
+        if (AdapterMethodHandle.canCollectArguments(oldType, ctype, foldPos, true)) {
+            MethodHandle res = AdapterMethodHandle.makeCollectArguments(target, combiner, foldPos, true);
+            if (res != null)  return res;
+        }
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
+        if (foldPos != 0)  return null;
+        MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, 0);
+        MethodHandle gcombiner = convertArguments(combiner, ctype.generic(), ctype, 0);
+        if (ctype.returnType() == void.class) {
+            gtarget = dropArguments(gtarget, oldType.generic().insertParameterTypes(foldPos, Object.class), foldPos);
+        }
         if (gtarget == null || gcombiner == null)  return null;
         MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget);
-        MethodHandle result = convertArguments(gresult, newType, gresult.type(), null);
-        return result;
+        return convertArguments(gresult, newType, gresult.type(), 0);
     }
 
     static
@@ -802,6 +879,7 @@
             this.target = target;
             this.fallback = fallback;
         }
+        // FIXME: Build the control flow out of foldArguments.
         static MethodHandle make(MethodHandle test, MethodHandle target, MethodHandle fallback) {
             MethodType type = target.type();
             int nargs = type.parameterCount();
@@ -809,12 +887,12 @@
                 MethodHandle invoke = INVOKES[nargs];
                 MethodType gtype = type.generic();
                 assert(invoke.type().dropParameterTypes(0,1) == gtype);
-                MethodHandle gtest = convertArguments(test, gtype.changeReturnType(boolean.class), test.type(), null);
-                MethodHandle gtarget = convertArguments(target, gtype, type, null);
-                MethodHandle gfallback = convertArguments(fallback, gtype, type, null);
+                MethodHandle gtest = convertArguments(test, gtype.changeReturnType(boolean.class), test.type(), 0);
+                MethodHandle gtarget = convertArguments(target, gtype, type, 0);
+                MethodHandle gfallback = convertArguments(fallback, gtype, type, 0);
                 if (gtest == null || gtarget == null || gfallback == null)  return null;
                 MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback);
-                return convertArguments(gguard, type, gtype, null);
+                return convertArguments(gguard, type, gtype, 0);
             } else {
                 MethodHandle invoke = VARARGS_INVOKE;
                 MethodType gtype = MethodType.genericMethodType(1);
@@ -925,8 +1003,9 @@
         GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
             this(INVOKES[target.type().parameterCount()], target, exType, catcher);
         }
-       GuardWithCatch(MethodHandle invoker,
-                      MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
+        // FIXME: Build the control flow out of foldArguments.
+        GuardWithCatch(MethodHandle invoker,
+                       MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
             super(invoker);
             this.target = target;
             this.exType = exType;
@@ -1057,11 +1136,11 @@
         if (nargs < GuardWithCatch.INVOKES.length) {
             MethodType gtype = type.generic();
             MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
-            MethodHandle gtarget = convertArguments(target, gtype, type, null);
-            MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, null);
+            MethodHandle gtarget = convertArguments(target, gtype, type, 0);
+            MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, 0);
             MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher);
             if (gtarget == null || gcatcher == null || gguard == null)  return null;
-            return convertArguments(gguard, type, gtype, null);
+            return convertArguments(gguard, type, gtype, 0);
         } else {
             MethodType gtype = MethodType.genericMethodType(0, true);
             MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Wed May 18 13:19:32 2011 +0200
@@ -115,6 +115,8 @@
 
     /** Which conv-ops are implemented by the JVM? */
     static final int CONV_OP_IMPLEMENTED_MASK;
+    /** Derived mode flag.  Only false on some old JVM implementations. */
+    static final boolean HAVE_RICOCHET_FRAMES;
 
     private static native void registerNatives();
     static {
@@ -141,6 +143,7 @@
         if (CONV_OP_IMPLEMENTED_MASK_ == 0)
             CONV_OP_IMPLEMENTED_MASK_ = DEFAULT_CONV_OP_IMPLEMENTED_MASK;
         CONV_OP_IMPLEMENTED_MASK = CONV_OP_IMPLEMENTED_MASK_;
+        HAVE_RICOCHET_FRAMES = (CONV_OP_IMPLEMENTED_MASK & (1<<OP_COLLECT_ARGS)) != 0;
     }
 
     // All compile-time constants go here.
@@ -186,25 +189,26 @@
          */
         static final int
             OP_RETYPE_ONLY   = 0x0, // no argument changes; straight retype
-            OP_RETYPE_RAW    = 0x1, // no argument changes; straight retype
+            OP_RETYPE_RAW    = 0x1, // straight retype, trusted (void->int, Object->T)
             OP_CHECK_CAST    = 0x2, // ref-to-ref conversion; requires a Class argument
             OP_PRIM_TO_PRIM  = 0x3, // converts from one primitive to another
             OP_REF_TO_PRIM   = 0x4, // unboxes a wrapper to produce a primitive
-            OP_PRIM_TO_REF   = 0x5, // boxes a primitive into a wrapper (NYI)
+            OP_PRIM_TO_REF   = 0x5, // boxes a primitive into a wrapper
             OP_SWAP_ARGS     = 0x6, // swap arguments (vminfo is 2nd arg)
             OP_ROT_ARGS      = 0x7, // rotate arguments (vminfo is displaced arg)
             OP_DUP_ARGS      = 0x8, // duplicates one or more arguments (at TOS)
             OP_DROP_ARGS     = 0x9, // remove one or more argument slots
-            OP_COLLECT_ARGS  = 0xA, // combine one or more arguments into a varargs (NYI)
+            OP_COLLECT_ARGS  = 0xA, // combine arguments using an auxiliary function
             OP_SPREAD_ARGS   = 0xB, // expand in place a varargs array (of known size)
-            OP_FLYBY         = 0xC, // operate first on reified argument list (NYI)
-            OP_RICOCHET      = 0xD, // run an adapter chain on the return value (NYI)
+            OP_FOLD_ARGS     = 0xC, // combine but do not remove arguments; prepend result
+            //OP_UNUSED_13   = 0xD, // unused code, perhaps for reified argument lists
             CONV_OP_LIMIT    = 0xE; // limit of CONV_OP enumeration
         /** Shift and mask values for decoding the AMH.conversion field.
          *  These numbers are shared with the JVM for creating AMHs.
          */
         static final int
             CONV_OP_MASK     = 0xF00, // this nybble contains the conversion op field
+            CONV_TYPE_MASK   = 0x0F,  // fits T_ADDRESS and below
             CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
             CONV_VMINFO_SHIFT     =  0, // position of bits in CONV_VMINFO_MASK
             CONV_OP_SHIFT         =  8, // position of bits in CONV_OP_MASK
@@ -244,8 +248,9 @@
             T_LONG     = 11,
             T_OBJECT   = 12,
             //T_ARRAY    = 13
-            T_VOID     = 14;
+            T_VOID     = 14,
             //T_ADDRESS  = 15
+            T_ILLEGAL  = 99;
 
         /**
          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
@@ -273,16 +278,29 @@
             try {
                 Field con = Constants.class.getDeclaredField(name);
                 int jval = con.getInt(null);
-                if (jval != vmval)
-                    throw new InternalError(name+": JVM has "+vmval+" while Java has "+jval);
+                if (jval == vmval)  continue;
+                String err = (name+": JVM has "+vmval+" while Java has "+jval);
+                if (name.equals("CONV_OP_LIMIT")) {
+                    System.err.println("warning: "+err);
+                    continue;
+                }
+                throw new InternalError(err);
             } catch (Exception ex) {
+                if (ex instanceof NoSuchFieldException) {
+                    String err = (name+": JVM has "+vmval+" which Java does not define");
+                    // ignore exotic ops the JVM cares about; we just wont issue them
+                    if (name.startsWith("OP_") || name.startsWith("GC_")) {
+                        System.err.println("warning: "+err);
+                        continue;
+                    }
+                }
                 throw new InternalError(name+": access failed, got "+ex);
             }
         }
         return true;
     }
     static {
-        verifyConstants();
+        assert(verifyConstants());
     }
 
     // Up-calls from the JVM.
@@ -313,7 +331,7 @@
     }
 
     /**
-     * The JVM wants to use a MethodType with invokeGeneric.  Give the runtime fair warning.
+     * The JVM wants to use a MethodType with inexact invoke.  Give the runtime fair warning.
      */
     static void notifyGenericMethodType(MethodType type) {
         type.form().notifyGenericMethodType();
@@ -323,15 +341,39 @@
      * The JVM wants to raise an exception.  Here's the path.
      */
     static void raiseException(int code, Object actual, Object required) {
-        String message;
+        String message = null;
+        switch (code) {
+        case 190: // arraylength
+            try {
+                String reqLength = "";
+                if (required instanceof AdapterMethodHandle) {
+                    int conv = ((AdapterMethodHandle)required).getConversion();
+                    int spChange = AdapterMethodHandle.extractStackMove(conv);
+                    reqLength = " of length "+(spChange+1);
+                }
+                int actualLength = actual == null ? 0 : java.lang.reflect.Array.getLength(actual);
+                message = "required array"+reqLength+", but encountered wrong length "+actualLength;
+                break;
+            } catch (IllegalArgumentException ex) {
+            }
+            required = Object[].class;  // should have been an array
+            code = 192; // checkcast
+            break;
+        }
         // disregard the identity of the actual object, if it is not a class:
-        if (!(actual instanceof Class) && !(actual instanceof MethodType))
-            actual = actual.getClass();
-        if (actual != null)
-            message = "required "+required+" but encountered "+actual;
-        else
-            message = "required "+required;
+        if (message == null) {
+            if (!(actual instanceof Class) && !(actual instanceof MethodType))
+                actual = actual.getClass();
+           if (actual != null)
+               message = "required "+required+" but encountered "+actual;
+           else
+               message = "required "+required;
+        }
         switch (code) {
+        case 190: // arraylength
+            throw new ArrayIndexOutOfBoundsException(message);
+        case 50: //_aaload
+            throw new ClassCastException(message);
         case 192: // checkcast
             throw new ClassCastException(message);
         default:
@@ -365,4 +407,13 @@
             throw err;
         }
     }
+
+    /**
+     * This assertion marks code which was written before ricochet frames were implemented.
+     * Such code will go away when the ports catch up.
+     */
+    static boolean workaroundWithoutRicochetFrames() {
+        assert(!HAVE_RICOCHET_FRAMES) : "this code should not be executed if `-XX:+UseRicochetFrames is enabled";
+        return true;
+    }
 }
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java	Wed May 18 13:19:32 2011 +0200
@@ -63,8 +63,17 @@
     }
 
     static void checkSpreadArgument(Object av, int n) {
-        if (av == null ? n != 0 : ((Object[])av).length != n)
-            throw newIllegalArgumentException("Array is not of length "+n);
+        if (av == null) {
+            if (n == 0)  return;
+        } else if (av instanceof Object[]) {
+            int len = ((Object[])av).length;
+            if (len == n)  return;
+        } else {
+            int len = java.lang.reflect.Array.getLength(av);
+            if (len == n)  return;
+        }
+        // fall through to error:
+        throw newIllegalArgumentException("Array is not of length "+n);
     }
 
     // handy shared exception makers (they simplify the common case code)
@@ -80,6 +89,9 @@
     /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj) {
         return new IllegalArgumentException(message(message, obj));
     }
+    /*non-public*/ static RuntimeException newIllegalArgumentException(String message, Object obj, Object obj2) {
+        return new IllegalArgumentException(message(message, obj, obj2));
+    }
     /*non-public*/ static Error uncaughtException(Exception ex) {
         Error err = new InternalError("uncaught exception");
         err.initCause(ex);
@@ -89,4 +101,8 @@
         if (obj != null)  message = message + ": " + obj;
         return message;
     }
+    private static String message(String message, Object obj, Object obj2) {
+        if (obj != null || obj2 != null)  message = message + ": " + obj + ", " + obj2;
+        return message;
+    }
 }
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java	Wed May 18 13:19:32 2011 +0200
@@ -190,7 +190,7 @@
      * is not symbolically accessible from the lookup class's loader,
      * the lookup can still succeed.
      * For example, lookups for {@code MethodHandle.invokeExact} and
-     * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
+     * {@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
@@ -590,10 +590,10 @@
          * Because of the general equivalence 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 invokeGeneric}, the resulting
+         * {@code invokeExact} or {@code invoke}, the resulting
          * method handle is equivalent to one produced by
          * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
-         * {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}
+         * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
          * with the same {@code type} argument.
          *
          * @param refc the class or interface from which the method is accessed
@@ -1080,7 +1080,7 @@
             MethodType rawType = mh.type();
             if (rawType.parameterType(0) == caller)  return mh;
             MethodType narrowType = rawType.changeParameterType(0, caller);
-            MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, null);
+            MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, 0);
             return fixVarargs(narrowMH, mh);
         }
 
@@ -1148,7 +1148,7 @@
      * <li>an {@code Object[]} array containing more arguments
      * </ul>
      * <p>
-     * The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with
+     * The invoker will behave like a call to {@link MethodHandle#invoke invoke} with
      * the indicated {@code type}.
      * That is, if the target is exactly of the given {@code type}, it will behave
      * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
@@ -1166,7 +1166,7 @@
      * <p>
      * This method is equivalent to the following code (though it may be more efficient):
      * <p><blockquote><pre>
-MethodHandle invoker = MethodHandles.genericInvoker(type);
+MethodHandle invoker = MethodHandles.invoker(type);
 int spreadArgCount = type.parameterCount - objectArgCount;
 invoker = invoker.asSpreader(Object[].class, spreadArgCount);
 return invoker;
@@ -1186,7 +1186,7 @@
 
     /**
      * Produces a special <em>invoker method handle</em> which can be used to
-     * invoke any method handle of the given type, as if by {@code invokeExact}.
+     * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
      * The resulting invoker will have a type which is
      * exactly equal to the desired type, except that it will accept
      * an additional leading argument of type {@code MethodHandle}.
@@ -1203,7 +1203,7 @@
      * For example, to emulate an {@code invokeExact} call to a variable method
      * handle {@code M}, extract its type {@code T},
      * look up the invoker method {@code X} for {@code T},
-     * and call the invoker method, as {@code X.invokeGeneric(T, A...)}.
+     * and call the invoker method, as {@code X.invoke(T, A...)}.
      * (It would not work to call {@code X.invokeExact}, since the type {@code T}
      * is unknown.)
      * If spreading, collecting, or other argument transformations are required,
@@ -1212,7 +1212,7 @@
      * <p>
      * <em>(Note:  The invoker method is not available via the Core Reflection API.
      * An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke}
-     * on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an
+     * 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.
@@ -1226,20 +1226,20 @@
 
     /**
      * Produces a special <em>invoker method handle</em> which can be used to
-     * invoke any method handle of the given type, as if by {@code invokeGeneric}.
+     * invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}.
      * The resulting invoker will have a type which is
      * exactly equal to the desired type, except that it will accept
      * an additional leading argument of type {@code MethodHandle}.
      * <p>
      * Before invoking its target, the invoker will apply reference casts as
-     * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}.
-     * The return value of the invoker will be an {@code Object} reference,
-     * boxing a primitive value if the original type returns a primitive,
-     * and always null if the original type returns void.
+     * necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}.
+     * Similarly, the return value will be converted as necessary.
+     * 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>
      * This method is equivalent to the following code (though it may be more efficient):
      * <p><blockquote><pre>
-publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
+publicLookup().findVirtual(MethodHandle.class, "invoke", type)
      * </pre></blockquote>
      * <p>
      * This method throws no reflective or security exceptions.
@@ -1247,8 +1247,17 @@
      * @return a method handle suitable for invoking any method handle convertible to the given type
      */
     static public
+    MethodHandle invoker(MethodType type) {
+        return type.invokers().generalInvoker();
+    }
+
+    /**
+     * <em>Temporary alias</em> for {@link #invoker}, for backward compatibility with some versions of JSR 292.
+     * @deprecated Will be removed for JSR 292 Proposed Final Draft.
+     */
+    public static
     MethodHandle genericInvoker(MethodType type) {
-        return type.invokers().genericInvoker();
+        return invoker(type);
     }
 
     /**
@@ -1368,18 +1377,7 @@
      */
     public static
     MethodHandle convertArguments(MethodHandle target, MethodType newType) {
-        MethodType oldType = target.type();
-        if (oldType.equals(newType))
-            return target;
-        MethodHandle res = null;
-        try {
-            res = MethodHandleImpl.convertArguments(target,
-                                                    newType, oldType, null);
-        } catch (IllegalArgumentException ex) {
-        }
-        if (res == null)
-            throw new WrongMethodTypeException("cannot convert to "+newType+": "+target);
-        return res;
+        return MethodHandleImpl.convertArguments(target, newType, 1);
     }
 
     /**
@@ -1422,7 +1420,7 @@
      */
     public static
     MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
-        return convertArguments(target, newType);  // FIXME!
+        return MethodHandleImpl.convertArguments(target, newType, 2);
     }
 
     /*
@@ -1517,23 +1515,32 @@
     MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
         MethodType oldType = target.type();
         checkReorder(reorder, newType, oldType);
-        return MethodHandleImpl.convertArguments(target,
+        return MethodHandleImpl.permuteArguments(target,
                                                  newType, oldType,
                                                  reorder);
     }
 
     private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
+        if (newType.returnType() != oldType.returnType())
+            throw newIllegalArgumentException("return types do not match",
+                    oldType, newType);
         if (reorder.length == oldType.parameterCount()) {
             int limit = newType.parameterCount();
             boolean bad = false;
-            for (int i : reorder) {
+            for (int j = 0; j < reorder.length; j++) {
+                int i = reorder[j];
                 if (i < 0 || i >= limit) {
                     bad = true; break;
                 }
+                Class<?> src = newType.parameterType(i);
+                Class<?> dst = oldType.parameterType(j);
+                if (src != dst)
+                    throw newIllegalArgumentException("parameter types do not match after reorder",
+                            oldType, newType);
             }
             if (!bad)  return;
         }
-        throw newIllegalArgumentException("bad reorder array");
+        throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
     }
 
     /**
@@ -1622,7 +1629,7 @@
             if (type == void.class)
                 throw newIllegalArgumentException("void type");
             Wrapper w = Wrapper.forPrimitiveType(type);
-            return identity(type).bindTo(w.convert(value, type));
+            return insertArguments(identity(type), 0, w.convert(value, type));
         } else {
             return identity(type).bindTo(type.cast(value));
         }
@@ -1857,7 +1864,8 @@
     MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
         MethodType targetType = target.type();
         MethodHandle adapter = target;
-        MethodType adapterType = targetType;
+        MethodType adapterType = null;
+        assert((adapterType = targetType) != null);
         int maxPos = targetType.parameterCount();
         if (pos + filters.length > maxPos)
             throw newIllegalArgumentException("too many filters");
@@ -1865,19 +1873,23 @@
         for (MethodHandle filter : filters) {
             curPos += 1;
             if (filter == null)  continue;  // ignore null elements of filters
-            MethodType filterType = filter.type();
-            if (filterType.parameterCount() != 1
-                || filterType.returnType() != targetType.parameterType(curPos))
-                throw newIllegalArgumentException("target and filter types do not match");
-            adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
-            adapter = MethodHandleImpl.filterArgument(adapter, curPos, filter);
+            adapter = filterArgument(adapter, curPos, filter);
+            assert((adapterType = adapterType.changeParameterType(curPos, filter.type().parameterType(0))) != null);
         }
-        MethodType midType = adapter.type();
-        if (midType != adapterType)
-            adapter = MethodHandleImpl.convertArguments(adapter, adapterType, midType, null);
+        assert(adapterType.equals(adapter.type()));
         return adapter;
     }
 
+    /*non-public*/ static
+    MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
+        MethodType targetType = target.type();
+        MethodType filterType = filter.type();
+        if (filterType.parameterCount() != 1
+            || filterType.returnType() != targetType.parameterType(pos))
+            throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+        return MethodHandleImpl.filterArgument(target, pos, filter);
+    }
+
     /**
      * Adapts a target method handle {@code target} by post-processing
      * its return value with a unary filter function.
@@ -1913,14 +1925,26 @@
     MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
         MethodType targetType = target.type();
         MethodType filterType = filter.type();
-        if (filterType.parameterCount() != 1
-            || filterType.parameterType(0) != targetType.returnType())
-            throw newIllegalArgumentException("target and filter types do not match");
+        Class<?> rtype = targetType.returnType();
+        int filterValues = filterType.parameterCount();
+        if (filterValues == 0
+                ? (rtype != void.class)
+                : (rtype != filterType.parameterType(0)))
+            throw newIllegalArgumentException("target and filter types do not match", target, filter);
         // result = fold( lambda(retval, arg...) { filter(retval) },
         //                lambda(        arg...) { target(arg...) } )
+        MethodType newType = targetType.changeReturnType(filterType.returnType());
+        MethodHandle result = null;
+        if (AdapterMethodHandle.canCollectArguments(filterType, targetType, 0, false)) {
+            result = AdapterMethodHandle.makeCollectArguments(filter, target, 0, false);
+            if (result != null)  return result;
+        }
         // FIXME: Too many nodes here.
-        MethodHandle returner = dropArguments(filter, 1, targetType.parameterList());
-        return foldArguments(returner, target);
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
+        MethodHandle returner = dropArguments(filter, filterValues, targetType.parameterList());
+        result = foldArguments(returner, target);
+        assert(result.type().equals(newType));
+        return result;
     }
 
     /**
@@ -1972,16 +1996,23 @@
     MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
         MethodType targetType = target.type();
         MethodType combinerType = combiner.type();
+        int foldPos = 0;  // always at the head, at present
         int foldArgs = combinerType.parameterCount();
-        boolean ok = (targetType.parameterCount() >= 1 + foldArgs);
-        if (ok && !combinerType.parameterList().equals(targetType.parameterList().subList(1, foldArgs+1)))
+        int foldVals = combinerType.returnType() == void.class ? 0 : 1;
+        int afterInsertPos = foldPos + foldVals;
+        boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
+        if (ok && !(combinerType.parameterList()
+                    .equals(targetType.parameterList().subList(afterInsertPos,
+                                                               afterInsertPos + foldArgs))))
             ok = false;
-        if (ok && !combinerType.returnType().equals(targetType.parameterType(0)))
+        if (ok && foldVals != 0 && !combinerType.returnType().equals(targetType.parameterType(0)))
             ok = false;
         if (!ok)
             throw misMatchedTypes("target and combiner types", targetType, combinerType);
-        MethodType newType = targetType.dropParameterTypes(0, 1);
-        return MethodHandleImpl.foldArguments(target, newType, combiner);
+        MethodType newType = targetType.dropParameterTypes(foldPos, afterInsertPos);
+        MethodHandle res = MethodHandleImpl.foldArguments(target, newType, foldPos, combiner);
+        if (res == null)  throw newIllegalArgumentException("cannot fold from "+newType+" to " +targetType);
+        return res;
     }
 
     /**
@@ -2142,7 +2173,7 @@
      * the given {@code target} on the incoming arguments,
      * and returning or throwing whatever the {@code target}
      * returns or throws.  The invocation will be as if by
-     * {@code target.invokeGeneric}.
+     * {@code target.invoke}.
      * The target's type will be checked before the
      * instance is created, as if by a call to {@code asType},
      * which may result in a {@code WrongMethodTypeException}.
--- a/jdk/src/share/classes/java/lang/invoke/MethodType.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java	Wed May 18 13:19:32 2011 +0200
@@ -25,6 +25,7 @@
 
 package java.lang.invoke;
 
+import sun.invoke.util.Wrapper;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -39,7 +40,7 @@
  * matched between a method handle and all its callers,
  * and the JVM's operations enforce this matching at, specifically
  * during calls to {@link MethodHandle#invokeExact MethodHandle.invokeExact}
- * and {@link MethodHandle#invokeGeneric MethodHandle.invokeGeneric}, and during execution
+ * and {@link MethodHandle#invoke MethodHandle.invoke}, and during execution
  * of {@code invokedynamic} instructions.
  * <p>
  * The structure is a return type accompanied by any number of parameter types.
@@ -262,18 +263,18 @@
      * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array.
      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * All parameters and the return type will be {@code Object},
-     * except the final varargs parameter if any, which will be {@code Object[]}.
-     * @param objectArgCount number of parameters (excluding the varargs parameter if any)
-     * @param varargs whether there will be a varargs parameter, of type {@code Object[]}
-     * @return a totally generic method type, given only its count of parameters and varargs
-     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
+     * except the final array parameter if any, which will be {@code Object[]}.
+     * @param objectArgCount number of parameters (excluding the final array parameter if any)
+     * @param finalArray whether there will be a trailing array parameter, of type {@code Object[]}
+     * @return a generally applicable method type, for all calls of the given fixed argument count and a collected array of further arguments
+     * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255 (or 254, if {@code finalArray})
      * @see #genericMethodType(int)
      */
     public static
-    MethodType genericMethodType(int objectArgCount, boolean varargs) {
+    MethodType genericMethodType(int objectArgCount, boolean finalArray) {
         MethodType mt;
         checkSlotCount(objectArgCount);
-        int ivarargs = (!varargs ? 0 : 1);
+        int ivarargs = (!finalArray ? 0 : 1);
         int ootIndex = objectArgCount*2 + ivarargs;
         if (ootIndex < objectOnlyTypes.length) {
             mt = objectOnlyTypes[ootIndex];
@@ -294,7 +295,7 @@
      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
      * All parameters and the return type will be Object.
      * @param objectArgCount number of parameters
-     * @return a totally generic method type, given only its count of parameters
+     * @return a generally applicable method type, for all calls of the given argument count
      * @throws IllegalArgumentException if {@code objectArgCount} is negative or greater than 255
      * @see #genericMethodType(int, boolean)
      */
@@ -626,6 +627,30 @@
         return sb.toString();
     }
 
+
+    /*non-public*/
+    boolean isConvertibleTo(MethodType newType) {
+        if (!canConvert(returnType(), newType.returnType()))
+            return false;
+        int argc = parameterCount();
+        if (argc != newType.parameterCount())
+            return false;
+        for (int i = 0; i < argc; i++) {
+            if (!canConvert(newType.parameterType(i), parameterType(i)))
+                return false;
+        }
+        return true;
+    }
+    private static boolean canConvert(Class<?> src, Class<?> dst) {
+        if (src == dst || dst == void.class)  return true;
+        if (src.isPrimitive() && dst.isPrimitive()) {
+        if (!Wrapper.forPrimitiveType(dst)
+                .isConvertibleFrom(Wrapper.forPrimitiveType(src)))
+            return false;
+        }
+        return true;
+    }
+
     /// Queries which have to do with the bytecode architecture
 
     /** Reports the number of JVM stack slots required to invoke a method
--- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java	Wed May 18 13:19:32 2011 +0200
@@ -46,6 +46,7 @@
     final long argCounts;               // packed slot & value counts
     final long primCounts;              // packed prim & double counts
     final int vmslots;                  // total number of parameter slots
+    private Object vmlayout;            // vm-specific information for calls
     final MethodType erasedType;        // the canonical erasure
 
     /*lazy*/ MethodType primsAsBoxes;   // replace prims by wrappers
@@ -59,7 +60,7 @@
     /*lazy*/ FromGeneric fromGeneric;   // convert cs. w/o prims to with
     /*lazy*/ SpreadGeneric[] spreadGeneric; // expand one argument to many
     /*lazy*/ FilterGeneric filterGeneric; // convert argument(s) on the fly
-    /*lazy*/ MethodHandle genericInvoker; // hook for invokeGeneric
+    /*lazy*/ MethodHandle genericInvoker; // hook for inexact invoke
 
     public MethodType erasedType() {
         return erasedType;
@@ -460,9 +461,9 @@
         if (genericInvoker != null)  return;
         try {
             // Trigger adapter creation.
-            genericInvoker = InvokeGeneric.genericInvokerOf(erasedType);
+            genericInvoker = InvokeGeneric.generalInvokerOf(erasedType);
         } catch (Exception ex) {
-            Error err = new InternalError("Exception while resolving invokeGeneric");
+            Error err = new InternalError("Exception while resolving inexact invoke");
             err.initCause(ex);
             throw err;
         }
--- a/jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java	Wed May 18 13:19:32 2011 +0200
@@ -66,6 +66,10 @@
         this.entryPoint = ep[0];
     }
 
+    static {
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
+    }
+
     /** From targetType remove the last spreadCount arguments, and instead
      *  append a simple Object argument.
      */
--- a/jdk/src/share/classes/java/lang/invoke/ToGeneric.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/ToGeneric.java	Wed May 18 13:19:32 2011 +0200
@@ -96,7 +96,7 @@
             ToGeneric va2 = ToGeneric.of(primsAtEnd);
             this.adapter = va2.adapter;
             if (true) throw new UnsupportedOperationException("NYI: primitive parameters must follow references; entryType = "+entryType);
-            this.entryPoint = MethodHandleImpl.convertArguments(
+            this.entryPoint = MethodHandleImpl.permuteArguments(
                     va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder);
             // example: for entryType of (int,Object,Object), the reordered
             // type is (Object,Object,int) and the order is {1,2,0},
@@ -128,7 +128,7 @@
                         assert(eptWithInts.parameterType(i) == int.class);
                         MethodType nextType = midType.changeParameterType(i, int.class);
                         rawEntryPoint = MethodHandleImpl.convertArguments(
-                                rawEntryPoint, nextType, midType, null);
+                                rawEntryPoint, nextType, midType, 0);
                         midType = nextType;
                     }
                 }
@@ -152,6 +152,10 @@
         this.invoker = makeRawArgumentFilter(invoker0, rawEntryTypeInit, entryType);
     }
 
+    static {
+        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
+    }
+
     /** A generic argument list will be created by a call of type 'raw'.
      *  The values need to be reboxed for to match 'cooked'.
      *  Do this on the fly.
@@ -171,7 +175,7 @@
                             invoker.type().generic(), invoker, 0, MethodHandle.class);
                 if (filteredInvoker == null)  throw new UnsupportedOperationException("NYI");
             }
-            MethodHandle reboxer = ValueConversions.rebox(dst, false);
+            MethodHandle reboxer = ValueConversions.rebox(dst);
             filteredInvoker = FilterGeneric.makeArgumentFilter(1+i, reboxer, filteredInvoker);
             if (filteredInvoker == null)  throw new InternalError();
         }
@@ -199,13 +203,13 @@
             assert(!rret.isPrimitive());
             if (rret == Object.class && !mustCast)
                 return null;
-            return ValueConversions.cast(tret, false);
+            return ValueConversions.cast(tret);
         } else if (tret == rret) {
-            return ValueConversions.unbox(tret, false);
+            return ValueConversions.unbox(tret);
         } else {
             assert(rret.isPrimitive());
             assert(tret == double.class ? rret == long.class : rret == int.class);
-            return ValueConversions.unboxRaw(tret, false);
+            return ValueConversions.unboxRaw(tret);
         }
     }
 
@@ -311,7 +315,7 @@
     }
 
     static Adapter buildAdapterFromBytecodes(MethodType entryPointType) {
-        throw new UnsupportedOperationException("NYI");
+        throw new UnsupportedOperationException("NYI: "+entryPointType);
     }
 
     /**
--- a/jdk/src/share/classes/java/lang/invoke/package-info.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/package-info.java	Wed May 18 13:19:32 2011 +0200
@@ -185,7 +185,7 @@
  * The method handle constant produced for such a method behaves as if
  * it were created by {@link java.lang.invoke.MethodHandle#asVarargsCollector asVarargsCollector}.
  * In other words, the constant method handle will exhibit variable arity,
- * when invoked via {@code invokeGeneric}.
+ * when invoked via {@code MethodHandle.invoke}.
  * On the other hand, its behavior with respect to {@code invokeExact} will be the same
  * as if the {@code varargs} bit were not set.
  * <p>
@@ -243,7 +243,7 @@
  * <li>optionally, one or more <a href="#args">additional static arguments</a> </li>
  * </ul>
  * The method handle is then applied to the other values as if by
- * {@link java.lang.invoke.MethodHandle#invokeGeneric invokeGeneric}.
+ * {@link java.lang.invoke.MethodHandle#invoke MethodHandle.invoke}.
  * The returned result must be a {@link java.lang.invoke.CallSite CallSite} (or a subclass).
  * The type of the call site's target must be exactly equal to the type
  * derived from the dynamic call site's type descriptor and passed to
@@ -251,7 +251,7 @@
  * The call site then becomes permanently linked to the dynamic call site.
  * <p>
  * As long as each bootstrap method can be correctly invoked
- * by <code>invokeGeneric</code>, its detailed type is arbitrary.
+ * by <code>MethodHandle.invoke</code>, its detailed type is arbitrary.
  * For example, the first argument could be {@code Object}
  * instead of {@code MethodHandles.Lookup}, and the return type
  * could also be {@code Object} instead of {@code CallSite}.
@@ -272,7 +272,7 @@
  *     (i.e., a {@code CONSTANT_Class}, {@code CONSTANT_MethodType},
  *     or {@code CONSTANT_MethodHandle} argument cannot be linked) </li>
  * <li>the bootstrap method has the wrong arity,
- *     causing {@code invokeGeneric} to throw {@code WrongMethodTypeException} </li>
+ *     causing {@code MethodHandle.invoke} to throw {@code WrongMethodTypeException} </li>
  * <li>the bootstrap method has a wrong argument or return type </li>
  * <li>the bootstrap method invocation completes abnormally </li>
  * <li>the result from the bootstrap invocation is not a reference to
@@ -381,10 +381,10 @@
  * those values will be passed as additional arguments to the method handle.
  * (Note that because there is a limit of 255 arguments to any method,
  * at most 252 extra arguments can be supplied.)
- * The bootstrap method will be invoked as if by either {@code invokeGeneric}
+ * The bootstrap method will be invoked as if by either {@code MethodHandle.invoke}
  * or {@code invokeWithArguments}.  (There is no way to tell the difference.)
  * <p>
- * The normal argument conversion rules for {@code invokeGeneric} apply to all stacked arguments.
+ * The normal argument conversion rules for {@code MethodHandle.invoke} apply to all stacked arguments.
  * For example, if a pushed value is a primitive type, it may be converted to a reference by boxing conversion.
  * If the bootstrap method is a variable arity method (its modifier bit {@code 0x0080} is set),
  * then some or all of the arguments specified here may be collected into a trailing array parameter.
@@ -419,8 +419,8 @@
  * For example, the fourth argument could be {@code MethodHandle},
  * if that is the type of the corresponding constant in
  * the {@code CONSTANT_InvokeDynamic} entry.
- * In that case, the {@code invokeGeneric} call will pass the extra method handle
- * constant as an {@code Object}, but the type matching machinery of {@code invokeGeneric}
+ * In that case, the {@code MethodHandle.invoke} call will pass the extra method handle
+ * constant as an {@code Object}, but the type matching machinery of {@code MethodHandle.invoke}
  * will cast the reference back to {@code MethodHandle} before invoking the bootstrap method.
  * (If a string constant were passed instead, by badly generated code, that cast would then fail,
  * resulting in a {@code BootstrapMethodError}.)
--- a/jdk/src/share/classes/java/net/SocketOption.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/net/SocketOption.java	Wed May 18 13:19:32 2011 +0200
@@ -38,7 +38,7 @@
  *
  * @since 1.7
  *
- * @see StandardSocketOption
+ * @see StandardSocketOptions
  */
 
 public interface SocketOption<T> {
--- a/jdk/src/share/classes/java/net/StandardSocketOption.java	Tue May 17 00:56:01 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,367 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.net;
-
-/**
- * Defines the <em>standard</em> socket options.
- *
- * <p> The {@link SocketOption#name name} of each socket option defined by this
- * class is its field name.
- *
- * <p> In this release, the socket options defined here are used by {@link
- * java.nio.channels.NetworkChannel network} channels in the {@link
- * java.nio.channels channels} package.
- *
- * @since 1.7
- */
-
-public final class StandardSocketOption {
-    private StandardSocketOption() { }
-
-    // -- SOL_SOCKET --
-
-    /**
-     * Allow transmission of broadcast datagrams.
-     *
-     * <p> The value of this socket option is a {@code Boolean} that represents
-     * whether the option is enabled or disabled. The option is specific to
-     * datagram-oriented sockets sending to {@link java.net.Inet4Address IPv4}
-     * broadcast addresses. When the socket option is enabled then the socket
-     * can be used to send <em>broadcast datagrams</em>.
-     *
-     * <p> The initial value of this socket option is {@code FALSE}. The socket
-     * option may be enabled or disabled at any time. Some operating systems may
-     * require that the Java virtual machine be started with implementation
-     * specific privileges to enable this option or send broadcast datagrams.
-     *
-     * @see <a href="http://www.ietf.org/rfc/rfc919.txt">RFC&nbsp;929:
-     * Broadcasting Internet Datagrams</a>
-     * @see DatagramSocket#setBroadcast
-     */
-    public static final SocketOption<Boolean> SO_BROADCAST =
-        new StdSocketOption<Boolean>("SO_BROADCAST", Boolean.class);
-
-    /**
-     * Keep connection alive.
-     *
-     * <p> The value of this socket option is a {@code Boolean} that represents
-     * whether the option is enabled or disabled. When the {@code SO_KEEPALIVE}
-     * option is enabled the operating system may use a <em>keep-alive</em>
-     * mechanism to periodically probe the other end of a connection when the
-     * connection is otherwise idle. The exact semantics of the keep alive
-     * mechanism is system dependent and therefore unspecified.
-     *
-     * <p> The initial value of this socket option is {@code FALSE}. The socket
-     * option may be enabled or disabled at any time.
-     *
-     * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122
-     * Requirements for Internet Hosts -- Communication Layers</a>
-     * @see Socket#setKeepAlive
-     */
-    public static final SocketOption<Boolean> SO_KEEPALIVE =
-        new StdSocketOption<Boolean>("SO_KEEPALIVE", Boolean.class);
-
-    /**
-     * The size of the socket send buffer.
-     *
-     * <p> The value of this socket option is an {@code Integer} that is the
-     * size of the socket send buffer in bytes. The socket send buffer is an
-     * output buffer used by the networking implementation. It may need to be
-     * increased for high-volume connections. The value of the socket option is
-     * a <em>hint</em> to the implementation to size the buffer and the actual
-     * size may differ. The socket option can be queried to retrieve the actual
-     * size.
-     *
-     * <p> For datagram-oriented sockets, the size of the send buffer may limit
-     * the size of the datagrams that may be sent by the socket. Whether
-     * datagrams larger than the buffer size are sent or discarded is system
-     * dependent.
-     *
-     * <p> The initial/default size of the socket send buffer and the range of
-     * allowable values is system dependent although a negative size is not
-     * allowed. An attempt to set the socket send buffer to larger than its
-     * maximum size causes it to be set to its maximum size.
-     *
-     * <p> An implementation allows this socket option to be set before the
-     * socket is bound or connected. Whether an implementation allows the
-     * socket send buffer to be changed after the socket is bound is system
-     * dependent.
-     *
-     * @see Socket#setSendBufferSize
-     */
-    public static final SocketOption<Integer> SO_SNDBUF =
-        new StdSocketOption<Integer>("SO_SNDBUF", Integer.class);
-
-
-    /**
-     * The size of the socket receive buffer.
-     *
-     * <p> The value of this socket option is an {@code Integer} that is the
-     * size of the socket receive buffer in bytes. The socket receive buffer is
-     * an input buffer used by the networking implementation. It may need to be
-     * increased for high-volume connections or decreased to limit the possible
-     * backlog of incoming data. The value of the socket option is a
-     * <em>hint</em> to the implementation to size the buffer and the actual
-     * size may differ.
-     *
-     * <p> For datagram-oriented sockets, the size of the receive buffer may
-     * limit the size of the datagrams that can be received. Whether datagrams
-     * larger than the buffer size can be received is system dependent.
-     * Increasing the socket receive buffer may be important for cases where
-     * datagrams arrive in bursts faster than they can be processed.
-     *
-     * <p> In the case of stream-oriented sockets and the TCP/IP protocol, the
-     * size of the socket receive buffer may be used when advertising the size
-     * of the TCP receive window to the remote peer.
-     *
-     * <p> The initial/default size of the socket receive buffer and the range
-     * of allowable values is system dependent although a negative size is not
-     * allowed. An attempt to set the socket receive buffer to larger than its
-     * maximum size causes it to be set to its maximum size.
-     *
-     * <p> An implementation allows this socket option to be set before the
-     * socket is bound or connected. Whether an implementation allows the
-     * socket receive buffer to be changed after the socket is bound is system
-     * dependent.
-     *
-     * @see <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC&nbsp;1323: TCP
-     * Extensions for High Performance</a>
-     * @see Socket#setReceiveBufferSize
-     * @see ServerSocket#setReceiveBufferSize
-     */
-    public static final SocketOption<Integer> SO_RCVBUF =
-        new StdSocketOption<Integer>("SO_RCVBUF", Integer.class);
-
-    /**
-     * Re-use address.
-     *
-     * <p> The value of this socket option is a {@code Boolean} that represents
-     * whether the option is enabled or disabled. The exact semantics of this
-     * socket option are socket type and system dependent.
-     *
-     * <p> In the case of stream-oriented sockets, this socket option will
-     * usually determine whether the socket can be bound to a socket address
-     * when a previous connection involving that socket address is in the
-     * <em>TIME_WAIT</em> state. On implementations where the semantics differ,
-     * and the socket option is not required to be enabled in order to bind the
-     * socket when a previous connection is in this state, then the
-     * implementation may choose to ignore this option.
-     *
-     * <p> For datagram-oriented sockets the socket option is used to allow
-     * multiple programs bind to the same address. This option should be enabled
-     * when the socket is to be used for Internet Protocol (IP) multicasting.
-     *
-     * <p> An implementation allows this socket option to be set before the
-     * socket is bound or connected. Changing the value of this socket option
-     * after the socket is bound has no effect. The default value of this
-     * socket option is system dependent.
-     *
-     * @see <a href="http://www.ietf.org/rfc/rfc793.txt">RFC&nbsp;793: Transmission
-     * Control Protocol</a>
-     * @see ServerSocket#setReuseAddress
-     */
-    public static final SocketOption<Boolean> SO_REUSEADDR =
-        new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
-
-    /**
-     * Linger on close if data is present.
-     *
-     * <p> The value of this socket option is an {@code Integer} that controls
-     * the action taken when unsent data is queued on the socket and a method
-     * to close the socket is invoked. If the value of the socket option is zero
-     * or greater, then it represents a timeout value, in seconds, known as the
-     * <em>linger interval</em>. The linger interval is the timeout for the
-     * {@code close} method to block while the operating system attempts to
-     * transmit the unsent data or it decides that it is unable to transmit the
-     * data. If the value of the socket option is less than zero then the option
-     * is disabled. In that case the {@code close} method does not wait until
-     * unsent data is transmitted; if possible the operating system will transmit
-     * any unsent data before the connection is closed.
-     *
-     * <p> This socket option is intended for use with sockets that are configured
-     * in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
-     * only. The behavior of the {@code close} method when this option is
-     * enabled on a non-blocking socket is not defined.
-     *
-     * <p> The initial value of this socket option is a negative value, meaning
-     * that the option is disabled. The option may be enabled, or the linger
-     * interval changed, at any time. The maximum value of the linger interval
-     * is system dependent. Setting the linger interval to a value that is
-     * greater than its maximum value causes the linger interval to be set to
-     * its maximum value.
-     *
-     * @see Socket#setSoLinger
-     */
-    public static final SocketOption<Integer> SO_LINGER =
-        new StdSocketOption<Integer>("SO_LINGER", Integer.class);
-
-
-    // -- IPPROTO_IP --
-
-    /**
-     * The Type of Service (ToS) octet in the Internet Protocol (IP) header.
-     *
-     * <p> The value of this socket option is an {@code Integer} representing
-     * the value of the ToS octet in IP packets sent by sockets to an {@link
-     * StandardProtocolFamily#INET IPv4} socket. The interpretation of the ToS
-     * octet is network specific and is not defined by this class. Further
-     * information on the ToS octet can be found in <a
-     * href="http://www.ietf.org/rfc/rfc1349.txt">RFC&nbsp;1349</a> and <a
-     * href="http://www.ietf.org/rfc/rfc2474.txt">RFC&nbsp;2474</a>. The value
-     * of the socket option is a <em>hint</em>. An implementation may ignore the
-     * value, or ignore specific values.
-     *
-     * <p> The initial/default value of the TOS field in the ToS octet is
-     * implementation specific but will typically be {@code 0}. For
-     * datagram-oriented sockets the option may be configured at any time after
-     * the socket has been bound. The new value of the octet is used when sending
-     * subsequent datagrams. It is system dependent whether this option can be
-     * queried or changed prior to binding the socket.
-     *
-     * <p> The behavior of this socket option on a stream-oriented socket, or an
-     * {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this
-     * release.
-     *
-     * @see DatagramSocket#setTrafficClass
-     */
-    public static final SocketOption<Integer> IP_TOS =
-        new StdSocketOption<Integer>("IP_TOS", Integer.class);
-
-    /**
-     * The network interface for Internet Protocol (IP) multicast datagrams.
-     *
-     * <p> The value of this socket option is a {@link NetworkInterface} that
-     * represents the outgoing interface for multicast datagrams sent by the
-     * datagram-oriented socket. For {@link StandardProtocolFamily#INET6 IPv6}
-     * sockets then it is system dependent whether setting this option also
-     * sets the outgoing interface for multlicast datagrams sent to IPv4
-     * addresses.
-     *
-     * <p> The initial/default value of this socket option may be {@code null}
-     * to indicate that outgoing interface will be selected by the operating
-     * system, typically based on the network routing tables. An implementation
-     * allows this socket option to be set after the socket is bound. Whether
-     * the socket option can be queried or changed prior to binding the socket
-     * is system dependent.
-     *
-     * @see java.nio.channels.MulticastChannel
-     * @see MulticastSocket#setInterface
-     */
-    public static final SocketOption<NetworkInterface> IP_MULTICAST_IF =
-        new StdSocketOption<NetworkInterface>("IP_MULTICAST_IF", NetworkInterface.class);
-
-    /**
-     * The <em>time-to-live</em> for Internet Protocol (IP) multicast datagrams.
-     *
-     * <p> The value of this socket option is an {@code Integer} in the range
-     * <tt>0&nbsp;<=&nbsp;value&nbsp;<=&nbsp;255</tt>. It is used to control
-     * the scope of multicast datagrams sent by the datagram-oriented socket.
-     * In the case of an {@link StandardProtocolFamily#INET IPv4} socket
-     * the option is the time-to-live (TTL) on multicast datagrams sent by the
-     * socket. Datagrams with a TTL of zero are not transmitted on the network
-     * but may be delivered locally. In the case of an {@link
-     * StandardProtocolFamily#INET6 IPv6} socket the option is the
-     * <em>hop limit</em> which is number of <em>hops</em> that the datagram can
-     * pass through before expiring on the network. For IPv6 sockets it is
-     * system dependent whether the option also sets the <em>time-to-live</em>
-     * on multicast datagrams sent to IPv4 addresses.
-     *
-     * <p> The initial/default value of the time-to-live setting is typically
-     * {@code 1}. An implementation allows this socket option to be set after
-     * the socket is bound. Whether the socket option can be queried or changed
-     * prior to binding the socket is system dependent.
-     *
-     * @see java.nio.channels.MulticastChannel
-     * @see MulticastSocket#setTimeToLive
-     */
-    public static final SocketOption<Integer> IP_MULTICAST_TTL =
-        new StdSocketOption<Integer>("IP_MULTICAST_TTL", Integer.class);
-
-    /**
-     * Loopback for Internet Protocol (IP) multicast datagrams.
-     *
-     * <p> The value of this socket option is a {@code Boolean} that controls
-     * the <em>loopback</em> of multicast datagrams. The value of the socket
-     * option represents if the option is enabled or disabled.
-     *
-     * <p> The exact semantics of this socket options are system dependent.
-     * In particular, it is system dependent whether the loopback applies to
-     * multicast datagrams sent from the socket or received by the socket.
-     * For {@link StandardProtocolFamily#INET6 IPv6} sockets then it is
-     * system dependent whether the option also applies to multicast datagrams
-     * sent to IPv4 addresses.
-     *
-     * <p> The initial/default value of this socket option is {@code TRUE}. An
-     * implementation allows this socket option to be set after the socket is
-     * bound. Whether the socket option can be queried or changed prior to
-     * binding the socket is system dependent.
-     *
-     * @see java.nio.channels.MulticastChannel
-     *  @see MulticastSocket#setLoopbackMode
-     */
-    public static final SocketOption<Boolean> IP_MULTICAST_LOOP =
-        new StdSocketOption<Boolean>("IP_MULTICAST_LOOP", Boolean.class);
-
-
-    // -- IPPROTO_TCP --
-
-    /**
-     * Disable the Nagle algorithm.
-     *
-     * <p> The value of this socket option is a {@code Boolean} that represents
-     * whether the option is enabled or disabled. The socket option is specific to
-     * stream-oriented sockets using the TCP/IP protocol. TCP/IP uses an algorithm
-     * known as <em>The Nagle Algorithm</em> to coalesce short segments and
-     * improve network efficiency.
-     *
-     * <p> The default value of this socket option is {@code FALSE}. The
-     * socket option should only be enabled in cases where it is known that the
-     * coalescing impacts performance. The socket option may be enabled at any
-     * time. In other words, the Nagle Algorithm can be disabled. Once the option
-     * is enabled, it is system dependent whether it can be subsequently
-     * disabled. If it cannot, then invoking the {@code setOption} method to
-     * disable the option has no effect.
-     *
-     * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122:
-     * Requirements for Internet Hosts -- Communication Layers</a>
-     * @see Socket#setTcpNoDelay
-     */
-    public static final SocketOption<Boolean> TCP_NODELAY =
-        new StdSocketOption<Boolean>("TCP_NODELAY", Boolean.class);
-
-
-    private static class StdSocketOption<T> implements SocketOption<T> {
-        private final String name;
-        private final Class<T> type;
-        StdSocketOption(String name, Class<T> type) {
-            this.name = name;
-            this.type = type;
-        }
-        @Override public String name() { return name; }
-        @Override public Class<T> type() { return type; }
-        @Override public String toString() { return name; }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/net/StandardSocketOptions.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Defines the <em>standard</em> socket options.
+ *
+ * <p> The {@link SocketOption#name name} of each socket option defined by this
+ * class is its field name.
+ *
+ * <p> In this release, the socket options defined here are used by {@link
+ * java.nio.channels.NetworkChannel network} channels in the {@link
+ * java.nio.channels channels} package.
+ *
+ * @since 1.7
+ */
+
+public final class StandardSocketOptions {
+    private StandardSocketOptions() { }
+
+    // -- SOL_SOCKET --
+
+    /**
+     * Allow transmission of broadcast datagrams.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. The option is specific to
+     * datagram-oriented sockets sending to {@link java.net.Inet4Address IPv4}
+     * broadcast addresses. When the socket option is enabled then the socket
+     * can be used to send <em>broadcast datagrams</em>.
+     *
+     * <p> The initial value of this socket option is {@code FALSE}. The socket
+     * option may be enabled or disabled at any time. Some operating systems may
+     * require that the Java virtual machine be started with implementation
+     * specific privileges to enable this option or send broadcast datagrams.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc919.txt">RFC&nbsp;929:
+     * Broadcasting Internet Datagrams</a>
+     * @see DatagramSocket#setBroadcast
+     */
+    public static final SocketOption<Boolean> SO_BROADCAST =
+        new StdSocketOption<Boolean>("SO_BROADCAST", Boolean.class);
+
+    /**
+     * Keep connection alive.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. When the {@code SO_KEEPALIVE}
+     * option is enabled the operating system may use a <em>keep-alive</em>
+     * mechanism to periodically probe the other end of a connection when the
+     * connection is otherwise idle. The exact semantics of the keep alive
+     * mechanism is system dependent and therefore unspecified.
+     *
+     * <p> The initial value of this socket option is {@code FALSE}. The socket
+     * option may be enabled or disabled at any time.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122
+     * Requirements for Internet Hosts -- Communication Layers</a>
+     * @see Socket#setKeepAlive
+     */
+    public static final SocketOption<Boolean> SO_KEEPALIVE =
+        new StdSocketOption<Boolean>("SO_KEEPALIVE", Boolean.class);
+
+    /**
+     * The size of the socket send buffer.
+     *
+     * <p> The value of this socket option is an {@code Integer} that is the
+     * size of the socket send buffer in bytes. The socket send buffer is an
+     * output buffer used by the networking implementation. It may need to be
+     * increased for high-volume connections. The value of the socket option is
+     * a <em>hint</em> to the implementation to size the buffer and the actual
+     * size may differ. The socket option can be queried to retrieve the actual
+     * size.
+     *
+     * <p> For datagram-oriented sockets, the size of the send buffer may limit
+     * the size of the datagrams that may be sent by the socket. Whether
+     * datagrams larger than the buffer size are sent or discarded is system
+     * dependent.
+     *
+     * <p> The initial/default size of the socket send buffer and the range of
+     * allowable values is system dependent although a negative size is not
+     * allowed. An attempt to set the socket send buffer to larger than its
+     * maximum size causes it to be set to its maximum size.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Whether an implementation allows the
+     * socket send buffer to be changed after the socket is bound is system
+     * dependent.
+     *
+     * @see Socket#setSendBufferSize
+     */
+    public static final SocketOption<Integer> SO_SNDBUF =
+        new StdSocketOption<Integer>("SO_SNDBUF", Integer.class);
+
+
+    /**
+     * The size of the socket receive buffer.
+     *
+     * <p> The value of this socket option is an {@code Integer} that is the
+     * size of the socket receive buffer in bytes. The socket receive buffer is
+     * an input buffer used by the networking implementation. It may need to be
+     * increased for high-volume connections or decreased to limit the possible
+     * backlog of incoming data. The value of the socket option is a
+     * <em>hint</em> to the implementation to size the buffer and the actual
+     * size may differ.
+     *
+     * <p> For datagram-oriented sockets, the size of the receive buffer may
+     * limit the size of the datagrams that can be received. Whether datagrams
+     * larger than the buffer size can be received is system dependent.
+     * Increasing the socket receive buffer may be important for cases where
+     * datagrams arrive in bursts faster than they can be processed.
+     *
+     * <p> In the case of stream-oriented sockets and the TCP/IP protocol, the
+     * size of the socket receive buffer may be used when advertising the size
+     * of the TCP receive window to the remote peer.
+     *
+     * <p> The initial/default size of the socket receive buffer and the range
+     * of allowable values is system dependent although a negative size is not
+     * allowed. An attempt to set the socket receive buffer to larger than its
+     * maximum size causes it to be set to its maximum size.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Whether an implementation allows the
+     * socket receive buffer to be changed after the socket is bound is system
+     * dependent.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC&nbsp;1323: TCP
+     * Extensions for High Performance</a>
+     * @see Socket#setReceiveBufferSize
+     * @see ServerSocket#setReceiveBufferSize
+     */
+    public static final SocketOption<Integer> SO_RCVBUF =
+        new StdSocketOption<Integer>("SO_RCVBUF", Integer.class);
+
+    /**
+     * Re-use address.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. The exact semantics of this
+     * socket option are socket type and system dependent.
+     *
+     * <p> In the case of stream-oriented sockets, this socket option will
+     * usually determine whether the socket can be bound to a socket address
+     * when a previous connection involving that socket address is in the
+     * <em>TIME_WAIT</em> state. On implementations where the semantics differ,
+     * and the socket option is not required to be enabled in order to bind the
+     * socket when a previous connection is in this state, then the
+     * implementation may choose to ignore this option.
+     *
+     * <p> For datagram-oriented sockets the socket option is used to allow
+     * multiple programs bind to the same address. This option should be enabled
+     * when the socket is to be used for Internet Protocol (IP) multicasting.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Changing the value of this socket option
+     * after the socket is bound has no effect. The default value of this
+     * socket option is system dependent.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc793.txt">RFC&nbsp;793: Transmission
+     * Control Protocol</a>
+     * @see ServerSocket#setReuseAddress
+     */
+    public static final SocketOption<Boolean> SO_REUSEADDR =
+        new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
+
+    /**
+     * Linger on close if data is present.
+     *
+     * <p> The value of this socket option is an {@code Integer} that controls
+     * the action taken when unsent data is queued on the socket and a method
+     * to close the socket is invoked. If the value of the socket option is zero
+     * or greater, then it represents a timeout value, in seconds, known as the
+     * <em>linger interval</em>. The linger interval is the timeout for the
+     * {@code close} method to block while the operating system attempts to
+     * transmit the unsent data or it decides that it is unable to transmit the
+     * data. If the value of the socket option is less than zero then the option
+     * is disabled. In that case the {@code close} method does not wait until
+     * unsent data is transmitted; if possible the operating system will transmit
+     * any unsent data before the connection is closed.
+     *
+     * <p> This socket option is intended for use with sockets that are configured
+     * in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
+     * only. The behavior of the {@code close} method when this option is
+     * enabled on a non-blocking socket is not defined.
+     *
+     * <p> The initial value of this socket option is a negative value, meaning
+     * that the option is disabled. The option may be enabled, or the linger
+     * interval changed, at any time. The maximum value of the linger interval
+     * is system dependent. Setting the linger interval to a value that is
+     * greater than its maximum value causes the linger interval to be set to
+     * its maximum value.
+     *
+     * @see Socket#setSoLinger
+     */
+    public static final SocketOption<Integer> SO_LINGER =
+        new StdSocketOption<Integer>("SO_LINGER", Integer.class);
+
+
+    // -- IPPROTO_IP --
+
+    /**
+     * The Type of Service (ToS) octet in the Internet Protocol (IP) header.
+     *
+     * <p> The value of this socket option is an {@code Integer} representing
+     * the value of the ToS octet in IP packets sent by sockets to an {@link
+     * StandardProtocolFamily#INET IPv4} socket. The interpretation of the ToS
+     * octet is network specific and is not defined by this class. Further
+     * information on the ToS octet can be found in <a
+     * href="http://www.ietf.org/rfc/rfc1349.txt">RFC&nbsp;1349</a> and <a
+     * href="http://www.ietf.org/rfc/rfc2474.txt">RFC&nbsp;2474</a>. The value
+     * of the socket option is a <em>hint</em>. An implementation may ignore the
+     * value, or ignore specific values.
+     *
+     * <p> The initial/default value of the TOS field in the ToS octet is
+     * implementation specific but will typically be {@code 0}. For
+     * datagram-oriented sockets the option may be configured at any time after
+     * the socket has been bound. The new value of the octet is used when sending
+     * subsequent datagrams. It is system dependent whether this option can be
+     * queried or changed prior to binding the socket.
+     *
+     * <p> The behavior of this socket option on a stream-oriented socket, or an
+     * {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this
+     * release.
+     *
+     * @see DatagramSocket#setTrafficClass
+     */
+    public static final SocketOption<Integer> IP_TOS =
+        new StdSocketOption<Integer>("IP_TOS", Integer.class);
+
+    /**
+     * The network interface for Internet Protocol (IP) multicast datagrams.
+     *
+     * <p> The value of this socket option is a {@link NetworkInterface} that
+     * represents the outgoing interface for multicast datagrams sent by the
+     * datagram-oriented socket. For {@link StandardProtocolFamily#INET6 IPv6}
+     * sockets then it is system dependent whether setting this option also
+     * sets the outgoing interface for multlicast datagrams sent to IPv4
+     * addresses.
+     *
+     * <p> The initial/default value of this socket option may be {@code null}
+     * to indicate that outgoing interface will be selected by the operating
+     * system, typically based on the network routing tables. An implementation
+     * allows this socket option to be set after the socket is bound. Whether
+     * the socket option can be queried or changed prior to binding the socket
+     * is system dependent.
+     *
+     * @see java.nio.channels.MulticastChannel
+     * @see MulticastSocket#setInterface
+     */
+    public static final SocketOption<NetworkInterface> IP_MULTICAST_IF =
+        new StdSocketOption<NetworkInterface>("IP_MULTICAST_IF", NetworkInterface.class);
+
+    /**
+     * The <em>time-to-live</em> for Internet Protocol (IP) multicast datagrams.
+     *
+     * <p> The value of this socket option is an {@code Integer} in the range
+     * <tt>0&nbsp;<=&nbsp;value&nbsp;<=&nbsp;255</tt>. It is used to control
+     * the scope of multicast datagrams sent by the datagram-oriented socket.
+     * In the case of an {@link StandardProtocolFamily#INET IPv4} socket
+     * the option is the time-to-live (TTL) on multicast datagrams sent by the
+     * socket. Datagrams with a TTL of zero are not transmitted on the network
+     * but may be delivered locally. In the case of an {@link
+     * StandardProtocolFamily#INET6 IPv6} socket the option is the
+     * <em>hop limit</em> which is number of <em>hops</em> that the datagram can
+     * pass through before expiring on the network. For IPv6 sockets it is
+     * system dependent whether the option also sets the <em>time-to-live</em>
+     * on multicast datagrams sent to IPv4 addresses.
+     *
+     * <p> The initial/default value of the time-to-live setting is typically
+     * {@code 1}. An implementation allows this socket option to be set after
+     * the socket is bound. Whether the socket option can be queried or changed
+     * prior to binding the socket is system dependent.
+     *
+     * @see java.nio.channels.MulticastChannel
+     * @see MulticastSocket#setTimeToLive
+     */
+    public static final SocketOption<Integer> IP_MULTICAST_TTL =
+        new StdSocketOption<Integer>("IP_MULTICAST_TTL", Integer.class);
+
+    /**
+     * Loopback for Internet Protocol (IP) multicast datagrams.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that controls
+     * the <em>loopback</em> of multicast datagrams. The value of the socket
+     * option represents if the option is enabled or disabled.
+     *
+     * <p> The exact semantics of this socket options are system dependent.
+     * In particular, it is system dependent whether the loopback applies to
+     * multicast datagrams sent from the socket or received by the socket.
+     * For {@link StandardProtocolFamily#INET6 IPv6} sockets then it is
+     * system dependent whether the option also applies to multicast datagrams
+     * sent to IPv4 addresses.
+     *
+     * <p> The initial/default value of this socket option is {@code TRUE}. An
+     * implementation allows this socket option to be set after the socket is
+     * bound. Whether the socket option can be queried or changed prior to
+     * binding the socket is system dependent.
+     *
+     * @see java.nio.channels.MulticastChannel
+     *  @see MulticastSocket#setLoopbackMode
+     */
+    public static final SocketOption<Boolean> IP_MULTICAST_LOOP =
+        new StdSocketOption<Boolean>("IP_MULTICAST_LOOP", Boolean.class);
+
+
+    // -- IPPROTO_TCP --
+
+    /**
+     * Disable the Nagle algorithm.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. The socket option is specific to
+     * stream-oriented sockets using the TCP/IP protocol. TCP/IP uses an algorithm
+     * known as <em>The Nagle Algorithm</em> to coalesce short segments and
+     * improve network efficiency.
+     *
+     * <p> The default value of this socket option is {@code FALSE}. The
+     * socket option should only be enabled in cases where it is known that the
+     * coalescing impacts performance. The socket option may be enabled at any
+     * time. In other words, the Nagle Algorithm can be disabled. Once the option
+     * is enabled, it is system dependent whether it can be subsequently
+     * disabled. If it cannot, then invoking the {@code setOption} method to
+     * disable the option has no effect.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122:
+     * Requirements for Internet Hosts -- Communication Layers</a>
+     * @see Socket#setTcpNoDelay
+     */
+    public static final SocketOption<Boolean> TCP_NODELAY =
+        new StdSocketOption<Boolean>("TCP_NODELAY", Boolean.class);
+
+
+    private static class StdSocketOption<T> implements SocketOption<T> {
+        private final String name;
+        private final Class<T> type;
+        StdSocketOption(String name, Class<T> type) {
+            this.name = name;
+            this.type = type;
+        }
+        @Override public String name() { return name; }
+        @Override public Class<T> type() { return type; }
+        @Override public String toString() { return name; }
+    }
+}
--- a/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -58,11 +58,11 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
  *     <td> The size of the socket receive buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
  *     <td> Re-use address </td>
  *   </tr>
  * </table>
--- a/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -68,23 +68,23 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
  *     <td> The size of the socket send buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
  *     <td> The size of the socket receive buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_KEEPALIVE SO_KEEPALIVE} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
  *     <td> Keep connection alive </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
  *     <td> Re-use address </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#TCP_NODELAY TCP_NODELAY} </td>
+ *     <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
  *     <td> Disable the Nagle algorithm </td>
  *   </tr>
  * </table>
--- a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -63,37 +63,37 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
  *     <td> The size of the socket send buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
  *     <td> The size of the socket receive buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
  *     <td> Re-use address </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_BROADCAST SO_BROADCAST} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_BROADCAST SO_BROADCAST} </td>
  *     <td> Allow transmission of broadcast datagrams </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#IP_TOS IP_TOS} </td>
+ *     <td> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </td>
  *     <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#IP_MULTICAST_IF IP_MULTICAST_IF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_IF IP_MULTICAST_IF} </td>
  *     <td> The network interface for Internet Protocol (IP) multicast datagrams </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#IP_MULTICAST_TTL
+ *     <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_TTL
  *       IP_MULTICAST_TTL} </td>
  *     <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast
  *       datagrams </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#IP_MULTICAST_LOOP
+ *     <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP
  *       IP_MULTICAST_LOOP} </td>
  *     <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
  *   </tr>
--- a/jdk/src/share/classes/java/nio/channels/MulticastChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/channels/MulticastChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -30,7 +30,7 @@
 import java.io.IOException;
 import java.net.ProtocolFamily;             // javadoc
 import java.net.StandardProtocolFamily;     // javadoc
-import java.net.StandardSocketOption;       // javadoc
+import java.net.StandardSocketOptions;      // javadoc
 
 /**
  * A network channel that supports Internet Protocol (IP) multicasting.
@@ -93,7 +93,7 @@
  * a specific address, rather than the wildcard address then it is implementation
  * specific if multicast datagrams are received by the socket. </p></li>
  *
- * <li><p> The {@link StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} option should be
+ * <li><p> The {@link StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} option should be
  * enabled prior to {@link NetworkChannel#bind binding} the socket. This is
  * required to allow multiple members of the group to bind to the same
  * address. </p></li>
@@ -107,9 +107,9 @@
  *     NetworkInterface ni = NetworkInterface.getByName("hme0");
  *
  *     DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
- *         .setOption(StandardSocketOption.SO_REUSEADDR, true)
+ *         .setOption(StandardSocketOptions.SO_REUSEADDR, true)
  *         .bind(new InetSocketAddress(5000))
- *         .setOption(StandardSocketOption.IP_MULTICAST_IF, ni);
+ *         .setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
  *
  *     InetAddress group = InetAddress.getByName("225.4.5.6");
  *
--- a/jdk/src/share/classes/java/nio/channels/NetworkChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/channels/NetworkChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -124,7 +124,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see java.net.StandardSocketOption
+     * @see java.net.StandardSocketOptions
      */
     <T> NetworkChannel setOption(SocketOption<T> name, T value) throws IOException;
 
@@ -144,7 +144,7 @@
      * @throws  IOException
      *          If an I/O error occurs
      *
-     * @see java.net.StandardSocketOption
+     * @see java.net.StandardSocketOptions
      */
     <T> T getOption(SocketOption<T> name) throws IOException;
 
--- a/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -52,11 +52,11 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
  *     <td> The size of the socket receive buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
  *     <td> Re-use address </td>
  *   </tr>
  * </table>
--- a/jdk/src/share/classes/java/nio/channels/SocketChannel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/channels/SocketChannel.java	Wed May 18 13:19:32 2011 +0200
@@ -72,28 +72,28 @@
  *     <th>Description</th>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
  *     <td> The size of the socket send buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
  *     <td> The size of the socket receive buffer </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_KEEPALIVE SO_KEEPALIVE} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
  *     <td> Keep connection alive </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
  *     <td> Re-use address </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_LINGER SO_LINGER} </td>
+ *     <td> {@link java.net.StandardSocketOptions#SO_LINGER SO_LINGER} </td>
  *     <td> Linger on close if data is present (when configured in blocking mode
  *          only) </td>
  *   </tr>
  *   <tr>
- *     <td> {@link java.net.StandardSocketOption#TCP_NODELAY TCP_NODELAY} </td>
+ *     <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
  *     <td> Disable the Nagle algorithm </td>
  *   </tr>
  * </table>
--- a/jdk/src/share/classes/java/nio/charset/Charset.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/charset/Charset.java	Wed May 18 13:19:32 2011 +0200
@@ -215,7 +215,7 @@
  * determined during virtual-machine startup and typically depends upon the
  * locale and charset being used by the underlying operating system. </p>
  *
- * <p>The {@link StandardCharset} class defines constants for each of the
+ * <p>The {@link StandardCharsets} class defines constants for each of the
  * standard charsets.
  *
  * <h4>Terminology</h4>
--- a/jdk/src/share/classes/java/nio/charset/StandardCharset.java	Tue May 17 00:56:01 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 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.nio.charset;
-
-/**
- * Constant definitions for the standard {@link Charset Charsets}. These
- * charsets are guaranteed to be available on every implementation of the Java
- * platform.
- *
- * @see <a href="Charset#standard">Standard Charsets</a>
- * @since 1.7
- */
-public final class StandardCharset {
-
-    private StandardCharset() {
-        throw new AssertionError("No java.nio.charset.StandardCharset instances for you!");
-    }
-    /**
-     * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
-     * Unicode character set
-     */
-    public static final Charset US_ASCII = Charset.forName("US-ASCII");
-    /**
-     * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
-     */
-    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
-    /**
-     * Eight-bit UCS Transformation Format
-     */
-    public static final Charset UTF_8 = Charset.forName("UTF-8");
-    /**
-     * Sixteen-bit UCS Transformation Format, big-endian byte order
-     */
-    public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
-    /**
-     * Sixteen-bit UCS Transformation Format, little-endian byte order
-     */
-    public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
-    /**
-     * Sixteen-bit UCS Transformation Format, byte order identified by an
-     * optional byte-order mark
-     */
-    public static final Charset UTF_16 = Charset.forName("UTF-16");
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/charset/StandardCharsets.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 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.nio.charset;
+
+/**
+ * Constant definitions for the standard {@link Charset Charsets}. These
+ * charsets are guaranteed to be available on every implementation of the Java
+ * platform.
+ *
+ * @see <a href="Charset#standard">Standard Charsets</a>
+ * @since 1.7
+ */
+public final class StandardCharsets {
+
+    private StandardCharsets() {
+        throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
+    }
+    /**
+     * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
+     * Unicode character set
+     */
+    public static final Charset US_ASCII = Charset.forName("US-ASCII");
+    /**
+     * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
+     */
+    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+    /**
+     * Eight-bit UCS Transformation Format
+     */
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+    /**
+     * Sixteen-bit UCS Transformation Format, big-endian byte order
+     */
+    public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+    /**
+     * Sixteen-bit UCS Transformation Format, little-endian byte order
+     */
+    public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+    /**
+     * Sixteen-bit UCS Transformation Format, byte order identified by an
+     * optional byte-order mark
+     */
+    public static final Charset UTF_16 = Charset.forName("UTF-16");
+}
--- a/jdk/src/share/classes/java/nio/file/Path.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/Path.java	Wed May 18 13:19:32 2011 +0200
@@ -72,7 +72,7 @@
  * directory and is UTF-8 encoded.
  * <pre>
  *     Path path = FileSystems.getDefault().getPath("logs", "access.log");
- *     BufferReader reader = Files.newBufferedReader(path, StandardCharset.UTF_8);
+ *     BufferReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
  * </pre>
  *
  * <a name="interop"><h4>Interoperability</h4></a>
@@ -609,11 +609,11 @@
      * directory can be watched. The {@code events} parameter is the events to
      * register and may contain the following events:
      * <ul>
-     *   <li>{@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE} -
+     *   <li>{@link StandardWatchEventKinds#ENTRY_CREATE ENTRY_CREATE} -
      *       entry created or moved into the directory</li>
-     *   <li>{@link StandardWatchEventKind#ENTRY_DELETE ENTRY_DELETE} -
+     *   <li>{@link StandardWatchEventKinds#ENTRY_DELETE ENTRY_DELETE} -
      *        entry deleted or moved out of the directory</li>
-     *   <li>{@link StandardWatchEventKind#ENTRY_MODIFY ENTRY_MODIFY} -
+     *   <li>{@link StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} -
      *        entry in directory was modified</li>
      * </ul>
      *
@@ -622,7 +622,7 @@
      * that locates the directory entry that is created, deleted, or modified.
      *
      * <p> The set of events may include additional implementation specific
-     * event that are not defined by the enum {@link StandardWatchEventKind}
+     * event that are not defined by the enum {@link StandardWatchEventKinds}
      *
      * <p> The {@code modifiers} parameter specifies <em>modifiers</em> that
      * qualify how the directory is registered. This release does not define any
--- a/jdk/src/share/classes/java/nio/file/StandardWatchEventKind.java	Tue May 17 00:56:01 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact 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.nio.file;
-
-/**
- * Defines the <em>standard</em> event kinds.
- *
- * @since 1.7
- */
-
-public final class StandardWatchEventKind {
-    private StandardWatchEventKind() { }
-
-    /**
-     * A special event to indicate that events may have been lost or
-     * discarded.
-     *
-     * <p> The {@link WatchEvent#context context} for this event is
-     * implementation specific and may be {@code null}. The event {@link
-     * WatchEvent#count count} may be greater than {@code 1}.
-     *
-     * @see WatchService
-     */
-    public static final WatchEvent.Kind<Void> OVERFLOW =
-        new StdWatchEventKind<Void>("OVERFLOW", Void.class);
-
-    /**
-     * Directory entry created.
-     *
-     * <p> When a directory is registered for this event then the {@link WatchKey}
-     * is queued when it is observed that an entry is created in the directory
-     * or renamed into the directory. The event {@link WatchEvent#count count}
-     * for this event is always {@code 1}.
-     */
-    public static final WatchEvent.Kind<Path> ENTRY_CREATE =
-        new StdWatchEventKind<Path>("ENTRY_CREATE", Path.class);
-
-    /**
-     * Directory entry deleted.
-     *
-     * <p> When a directory is registered for this event then the {@link WatchKey}
-     * is queued when it is observed that an entry is deleted or renamed out of
-     * the directory. The event {@link WatchEvent#count count} for this event
-     * is always {@code 1}.
-     */
-    public static final WatchEvent.Kind<Path> ENTRY_DELETE =
-        new StdWatchEventKind<Path>("ENTRY_DELETE", Path.class);
-
-    /**
-     * Directory entry modified.
-     *
-     * <p> When a directory is registered for this event then the {@link WatchKey}
-     * is queued when it is observed that an entry in the directory has been
-     * modified. The event {@link WatchEvent#count count} for this event is
-     * {@code 1} or greater.
-     */
-    public static final WatchEvent.Kind<Path> ENTRY_MODIFY =
-        new StdWatchEventKind<Path>("ENTRY_MODIFY", Path.class);
-
-    private static class StdWatchEventKind<T> implements WatchEvent.Kind<T> {
-        private final String name;
-        private final Class<T> type;
-        StdWatchEventKind(String name, Class<T> type) {
-            this.name = name;
-            this.type = type;
-        }
-        @Override public String name() { return name; }
-        @Override public Class<T> type() { return type; }
-        @Override public String toString() { return name; }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/nio/file/StandardWatchEventKinds.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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.nio.file;
+
+/**
+ * Defines the <em>standard</em> event kinds.
+ *
+ * @since 1.7
+ */
+
+public final class StandardWatchEventKinds {
+    private StandardWatchEventKinds() { }
+
+    /**
+     * A special event to indicate that events may have been lost or
+     * discarded.
+     *
+     * <p> The {@link WatchEvent#context context} for this event is
+     * implementation specific and may be {@code null}. The event {@link
+     * WatchEvent#count count} may be greater than {@code 1}.
+     *
+     * @see WatchService
+     */
+    public static final WatchEvent.Kind<Object> OVERFLOW =
+        new StdWatchEventKind<Object>("OVERFLOW", Object.class);
+
+    /**
+     * Directory entry created.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry is created in the directory
+     * or renamed into the directory. The event {@link WatchEvent#count count}
+     * for this event is always {@code 1}.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_CREATE =
+        new StdWatchEventKind<Path>("ENTRY_CREATE", Path.class);
+
+    /**
+     * Directory entry deleted.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry is deleted or renamed out of
+     * the directory. The event {@link WatchEvent#count count} for this event
+     * is always {@code 1}.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_DELETE =
+        new StdWatchEventKind<Path>("ENTRY_DELETE", Path.class);
+
+    /**
+     * Directory entry modified.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry in the directory has been
+     * modified. The event {@link WatchEvent#count count} for this event is
+     * {@code 1} or greater.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_MODIFY =
+        new StdWatchEventKind<Path>("ENTRY_MODIFY", Path.class);
+
+    private static class StdWatchEventKind<T> implements WatchEvent.Kind<T> {
+        private final String name;
+        private final Class<T> type;
+        StdWatchEventKind(String name, Class<T> type) {
+            this.name = name;
+            this.type = type;
+        }
+        @Override public String name() { return name; }
+        @Override public Class<T> type() { return type; }
+        @Override public String toString() { return name; }
+    }
+}
--- a/jdk/src/share/classes/java/nio/file/WatchEvent.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/WatchEvent.java	Wed May 18 13:19:32 2011 +0200
@@ -50,7 +50,7 @@
      * An event kind, for the purposes of identification.
      *
      * @since 1.7
-     * @see StandardWatchEventKind
+     * @see StandardWatchEventKinds
      */
     public static interface Kind<T> {
         /**
@@ -98,9 +98,9 @@
     /**
      * Returns the context for the event.
      *
-     * <p> In the case of {@link StandardWatchEventKind#ENTRY_CREATE ENTRY_CREATE},
-     * {@link StandardWatchEventKind#ENTRY_DELETE ENTRY_DELETE}, and {@link
-     * StandardWatchEventKind#ENTRY_MODIFY ENTRY_MODIFY} events the context is
+     * <p> In the case of {@link StandardWatchEventKinds#ENTRY_CREATE ENTRY_CREATE},
+     * {@link StandardWatchEventKinds#ENTRY_DELETE ENTRY_DELETE}, and {@link
+     * StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} events the context is
      * a {@code Path} that is the {@link Path#relativize relative} path between
      * the directory registered with the watch service, and the entry that is
      * created, deleted, or modified.
--- a/jdk/src/share/classes/java/nio/file/WatchService.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/WatchService.java	Wed May 18 13:19:32 2011 +0200
@@ -68,7 +68,7 @@
  * of events that it may accumulate. Where an implementation <em>knowingly</em>
  * discards events then it arranges for the key's {@link WatchKey#pollEvents
  * pollEvents} method to return an element with an event type of {@link
- * StandardWatchEventKind#OVERFLOW OVERFLOW}. This event can be used by the
+ * StandardWatchEventKinds#OVERFLOW OVERFLOW}. This event can be used by the
  * consumer as a trigger to re-examine the state of the object.
  *
  * <p> When an event is reported to indicate that a file in a watched directory
@@ -87,7 +87,7 @@
  * are detected, their timeliness, and whether their ordering is preserved are
  * highly implementation specific. For example, when a file in a watched
  * directory is modified then it may result in a single {@link
- * StandardWatchEventKind#ENTRY_MODIFY ENTRY_MODIFY} event in some
+ * StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} event in some
  * implementations but several events in other implementations. Short-lived
  * files (meaning files that are deleted very quickly after they are created)
  * may not be detected by primitive implementations that periodically poll the
--- a/jdk/src/share/classes/java/nio/file/Watchable.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/nio/file/Watchable.java	Wed May 18 13:19:32 2011 +0200
@@ -53,7 +53,7 @@
      * those specified by the {@code events} and {@code modifiers} parameters.
      * Changing the event set does not cause pending events for the object to be
      * discarded. Objects are automatically registered for the {@link
-     * StandardWatchEventKind#OVERFLOW OVERFLOW} event. This event is not
+     * StandardWatchEventKinds#OVERFLOW OVERFLOW} event. This event is not
      * required to be present in the array of events.
      *
      * <p> Otherwise the file system object has not yet been registered with the
--- a/jdk/src/share/classes/java/sql/BatchUpdateException.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/sql/BatchUpdateException.java	Wed May 18 13:19:32 2011 +0200
@@ -89,7 +89,7 @@
    * The <code>cause</code> is not initialized, and may subsequently be
    * initialized by a call to the
    * {@link Throwable#initCause(java.lang.Throwable)} method. The vendor code
-   * is intialized to 0.
+   * is initialized to 0.
    * <p>
    *
    * @param reason a description of the exception
@@ -188,7 +188,7 @@
      * @since 1.6
      */
     public BatchUpdateException(Throwable cause) {
-        this(null, null, 0, null, cause);
+        this((cause == null ? null : cause.toString()), null, 0, null, cause);
     }
 
     /**
@@ -214,7 +214,7 @@
      * @since 1.6
      */
     public BatchUpdateException(int []updateCounts , Throwable cause) {
-        this(null, null, 0, updateCounts, cause);
+        this((cause == null ? null : cause.toString()), null, 0, updateCounts, cause);
     }
 
     /**
--- a/jdk/src/share/classes/java/util/Formatter.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/Formatter.java	Wed May 18 13:19:32 2011 +0200
@@ -826,7 +826,7 @@
  *
  * <li> <a href="#dndec"><b>Float and Double</b></a>
  *
- * <li> <a href="#dndec"><b>BigDecimal</b></a>
+ * <li> <a href="#dnbdec"><b>BigDecimal</b></a>
  *
  * </ol>
  *
@@ -1362,7 +1362,7 @@
  * precision is not provided, then all of the digits as returned by {@link
  * Double#toHexString(double)} will be output.
  *
- * <p><a name="dndec"><b> BigDecimal </b></a>
+ * <p><a name="dnbdec"><b> BigDecimal </b></a>
  *
  * <p> The following conversions may be applied {@link java.math.BigDecimal
  * BigDecimal}.
@@ -1372,7 +1372,7 @@
  * <tr><td valign="top"> {@code 'e'}
  *     <td valign="top"> <tt>'&#92;u0065'</tt>
  *     <td> Requires the output to be formatted using <a
- *     name="scientific">computerized scientific notation</a>.  The <a
+ *     name="bscientific">computerized scientific notation</a>.  The <a
  *     href="#l10n algorithm">localization algorithm</a> is applied.
  *
  *     <p> The formatting of the magnitude <i>m</i> depends upon its value.
@@ -1427,11 +1427,11 @@
  *
  *     <p> If <i>m</i> is greater than or equal to 10<sup>-4</sup> but less
  *     than 10<sup>precision</sup> then it is represented in <i><a
- *     href="#decimal">decimal format</a></i>.
+ *     href="#bdecimal">decimal format</a></i>.
  *
  *     <p> If <i>m</i> is less than 10<sup>-4</sup> or greater than or equal to
  *     10<sup>precision</sup>, then it is represented in <i><a
- *     href="#scientific">computerized scientific notation</a></i>.
+ *     href="#bscientific">computerized scientific notation</a></i>.
  *
  *     <p> The total number of significant digits in <i>m</i> is equal to the
  *     precision.  If the precision is not specified, then the default value is
@@ -1447,7 +1447,7 @@
  *
  * <tr><td valign="top"> {@code 'f'}
  *     <td valign="top"> <tt>'&#92;u0066'</tt>
- *     <td> Requires the output to be formatted using <a name="decimal">decimal
+ *     <td> Requires the output to be formatted using <a name="bdecimal">decimal
  *     format</a>.  The <a href="#l10n algorithm">localization algorithm</a> is
  *     applied.
  *
--- a/jdk/src/share/classes/java/util/concurrent/Phaser.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/Phaser.java	Wed May 18 13:19:32 2011 +0200
@@ -159,7 +159,7 @@
  * void runTasks(List<Runnable> tasks) {
  *   final Phaser phaser = new Phaser(1); // "1" to register self
  *   // create and start threads
- *   for (Runnable task : tasks) {
+ *   for (final Runnable task : tasks) {
  *     phaser.register();
  *     new Thread() {
  *       public void run() {
--- a/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java	Wed May 18 13:19:32 2011 +0200
@@ -275,10 +275,14 @@
      * snapshot -- the thread may have since unblocked or blocked on a
      * different blocker object.
      *
+     * @param t the thread
      * @return the blocker
+     * @throws NullPointerException if argument is null
      * @since 1.6
      */
     public static Object getBlocker(Thread t) {
+        if (t == null)
+            throw new NullPointerException();
         return unsafe.getObjectVolatile(t, parkBlockerOffset);
     }
 
--- a/jdk/src/share/classes/java/util/logging/LogManager.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/logging/LogManager.java	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -342,12 +342,35 @@
     // already been created with the given name it is returned.
     // Otherwise a new logger instance is created and registered
     // in the LogManager global namespace.
+
+    // This method will always return a non-null Logger object.
+    // Synchronization is not required here. All synchronization for
+    // adding a new Logger object is handled by addLogger().
     Logger demandLogger(String name) {
         Logger result = getLogger(name);
         if (result == null) {
-            result = new Logger(name, null);
-            addLogger(result);
-            result = getLogger(name);
+            // only allocate the new logger once
+            Logger newLogger = new Logger(name, null);
+            do {
+                if (addLogger(newLogger)) {
+                    // We successfully added the new Logger that we
+                    // created above so return it without refetching.
+                    return newLogger;
+                }
+
+                // We didn't add the new Logger that we created above
+                // because another thread added a Logger with the same
+                // name after our null check above and before our call
+                // to addLogger(). We have to refetch the Logger because
+                // addLogger() returns a boolean instead of the Logger
+                // reference itself. However, if the thread that created
+                // the other Logger is not holding a strong reference to
+                // the other Logger, then it is possible for the other
+                // Logger to be GC'ed after we saw it in addLogger() and
+                // before we can refetch it. If it has been GC'ed then
+                // we'll just loop around and try again.
+                result = getLogger(name);
+            } while (result == null);
         }
         return result;
     }
--- a/jdk/src/share/classes/java/util/logging/Logger.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/logging/Logger.java	Wed May 18 13:19:32 2011 +0200
@@ -310,7 +310,20 @@
      * @return a suitable Logger
      * @throws NullPointerException if the name is null.
      */
-    public static synchronized Logger getLogger(String name) {
+
+    // Synchronization is not required here. All synchronization for
+    // adding a new Logger object is handled by LogManager.addLogger().
+    public static Logger getLogger(String name) {
+        // This method is intentionally not a wrapper around a call
+        // to getLogger(name, resourceBundleName). If it were then
+        // this sequence:
+        //
+        //     getLogger("Foo", "resourceBundleForFoo");
+        //     getLogger("Foo");
+        //
+        // would throw an IllegalArgumentException in the second call
+        // because the wrapper would result in an attempt to replace
+        // the existing "resourceBundleForFoo" with null.
         LogManager manager = LogManager.getLogManager();
         return manager.demandLogger(name);
     }
@@ -355,7 +368,10 @@
      *             a different resource bundle name.
      * @throws NullPointerException if the name is null.
      */
-    public static synchronized Logger getLogger(String name, String resourceBundleName) {
+
+    // Synchronization is not required here. All synchronization for
+    // adding a new Logger object is handled by LogManager.addLogger().
+    public static Logger getLogger(String name, String resourceBundleName) {
         LogManager manager = LogManager.getLogManager();
         Logger result = manager.demandLogger(name);
         if (result.resourceBundleName == null) {
@@ -417,7 +433,10 @@
      * @throws MissingResourceException if the resourceBundleName is non-null and
      *             no corresponding resource can be found.
      */
-    public static synchronized Logger getAnonymousLogger(String resourceBundleName) {
+
+    // Synchronization is not required here. All synchronization for
+    // adding a new anonymous Logger object is handled by doSetParent().
+    public static Logger getAnonymousLogger(String resourceBundleName) {
         LogManager manager = LogManager.getLogManager();
         // cleanup some Loggers that have been GC'ed
         manager.drainLoggerRefQueueBounded();
--- a/jdk/src/share/classes/java/util/regex/Pattern.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java	Wed May 18 13:19:32 2011 +0200
@@ -213,7 +213,7 @@
  *     <td headers="matches">A character in the Greek&nbsp;block (<a href="#ubc">block</a>)</td></tr>
  * <tr><td valign="top" headers="construct unicode"><tt>\p{Lu}</tt></td>
  *     <td headers="matches">An uppercase letter (<a href="#ucc">category</a>)</td></tr>
- * <tr><td valign="top" headers="construct unicode"><tt>\p{isAlphabetic}</tt></td>
+ * <tr><td valign="top" headers="construct unicode"><tt>\p{IsAlphabetic}</tt></td>
  *     <td headers="matches">An alphabetic character (<a href="#ubpc">binary property</a>)</td></tr>
  * <tr><td valign="top" headers="construct unicode"><tt>\p{Sc}</tt></td>
  *     <td headers="matches">A currency symbol</td></tr>
--- a/jdk/src/share/classes/java/util/zip/ZipCoder.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipCoder.java	Wed May 18 13:19:32 2011 +0200
@@ -28,7 +28,7 @@
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
-import java.nio.charset.StandardCharset;
+import java.nio.charset.StandardCharsets;
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
@@ -107,7 +107,7 @@
         if (isUTF8)
             return getBytes(s);
         if (utf8 == null)
-            utf8 = new ZipCoder(StandardCharset.UTF_8);
+            utf8 = new ZipCoder(StandardCharsets.UTF_8);
         return utf8.getBytes(s);
     }
 
@@ -116,7 +116,7 @@
         if (isUTF8)
             return toString(ba, len);
         if (utf8 == null)
-            utf8 = new ZipCoder(StandardCharset.UTF_8);
+            utf8 = new ZipCoder(StandardCharsets.UTF_8);
         return utf8.toString(ba, len);
     }
 
@@ -132,7 +132,7 @@
 
     private ZipCoder(Charset cs) {
         this.cs = cs;
-        this.isUTF8 = cs.name().equals(StandardCharset.UTF_8.name());
+        this.isUTF8 = cs.name().equals(StandardCharsets.UTF_8.name());
     }
 
     static ZipCoder get(Charset charset) {
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java	Wed May 18 13:19:32 2011 +0200
@@ -31,7 +31,7 @@
 import java.io.EOFException;
 import java.io.File;
 import java.nio.charset.Charset;
-import java.nio.charset.StandardCharset;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
 import java.util.Deque;
 import java.util.Enumeration;
@@ -141,7 +141,7 @@
      * @since 1.3
      */
     public ZipFile(File file, int mode) throws IOException {
-        this(file, mode, StandardCharset.UTF_8);
+        this(file, mode, StandardCharsets.UTF_8);
     }
 
     /**
--- a/jdk/src/share/classes/java/util/zip/ZipInputStream.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipInputStream.java	Wed May 18 13:19:32 2011 +0200
@@ -30,7 +30,7 @@
 import java.io.EOFException;
 import java.io.PushbackInputStream;
 import java.nio.charset.Charset;
-import java.nio.charset.StandardCharset;
+import java.nio.charset.StandardCharsets;
 import static java.util.zip.ZipConstants64.*;
 
 /**
@@ -76,7 +76,7 @@
      * @param in the actual input stream
      */
     public ZipInputStream(InputStream in) {
-        this(in, StandardCharset.UTF_8);
+        this(in, StandardCharsets.UTF_8);
     }
 
     /**
--- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java	Wed May 18 13:19:32 2011 +0200
@@ -28,7 +28,7 @@
 import java.io.OutputStream;
 import java.io.IOException;
 import java.nio.charset.Charset;
-import java.nio.charset.StandardCharset;
+import java.nio.charset.StandardCharsets;
 import java.util.Vector;
 import java.util.HashSet;
 import static java.util.zip.ZipConstants64.*;
@@ -101,7 +101,7 @@
      * @param out the actual output stream
      */
     public ZipOutputStream(OutputStream out) {
-        this(out, StandardCharset.UTF_8);
+        this(out, StandardCharsets.UTF_8);
     }
 
     /**
--- a/jdk/src/share/classes/javax/imageio/metadata/doc-files/jpeg_metadata.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/imageio/metadata/doc-files/jpeg_metadata.html	Wed May 18 13:19:32 2011 +0200
@@ -211,6 +211,20 @@
 
 <p>
 
+<a name=optcolor><b>Optional ColorSpace support:</b></a>
+Handling of PhotoYCC (YCC), PhotoYCCA (YCCA), RGBA and YCbCrA color spaces
+by the standard plugin, as described below, is dependent on capabilities
+of the libraries used to interpret the JPEG data. Thus all consequential
+behaviors are optional. If the support is not available when decoding,
+the color space will be treated as unrecognized and the appropriate
+default color space for the specified number of component channels
+may be used.
+When writing, an Exception may be thrown if no suitable conversion
+can be applied before encoding.
+But where the support for these color spaces is available, the behavior
+must be as documented. 
+<p>
+
 When reading, the contents of the stream are interpreted by the usual
 JPEG conventions, as follows:
 
@@ -241,8 +255,11 @@
        2-channel images are assumed to be grayscale with an alpha channel.
        For 3- and 4-channel images, the component ids are consulted.  If these
        values are 1-3 for a 3-channel image, then the image is assumed to be
-       YCbCr. If these values are 1-4 for a 4-channel image, then the image 
-       is assumed to be YCbCrA.  If these values are > 4, they are checked 
+       YCbCr. Subject to the availability of the
+       <a href=#optcolor>optional color space support</a>
+       described above, if these values are 1-4 for a 4-channel image,
+       then the image is assumed to be YCbCrA. 
+       If these values are > 4, they are checked 
        against the ASCII codes for 'R', 'G', 'B', 'A', 'C', 'c'.  These can 
        encode the following colorspaces:
        <p>
@@ -346,12 +363,16 @@
        component ids in the frame and scan headers are set to 1, 2, and 3.
 
 
-  <li> RGBA images are converted to YCbCrA, subsampled in the
+  <li> Subject to the <a href=#optcolor>optional library support</a>
+        described above,
+       RGBA images are converted to YCbCrA, subsampled in the
        chrominance channels by half both vertically and horizontally, and
        written without any special marker segments.  The component ids 
        in the frame and scan headers are set to 1, 2, 3, and 4.
 
-  <li> PhotoYCC and YCCAimages are subsampled by half in the chrominance
+  <li> Subject to the <a href=#optcolor>optional library support</a>
+       described above,
+       PhotoYCC and YCCAimages are subsampled by half in the chrominance
        channels both vertically and horizontally and written with an
        Adobe <code>APP14</code> marker segment and 'Y','C', and 'c' (and
        'A' if an alpha channel is present) as component ids in the frame
@@ -433,6 +454,8 @@
     </ul>
 
   <li> RGBA images:
+       Subject to the <a href=#optcolor>optional library support</a>
+       described above,
     <ul>
       <li> If an <code>app0JFIF</code> node is present in the metadata object,
            it is ignored and a warning is sent to listeners, as JFIF does not
@@ -456,6 +479,8 @@
     </ul>
 
   <li> PhotoYCC Images:
+       Subject to the <a href=#optcolor>optional library support</a>
+       described above,
     <ul>
       <li> If an <code>app0JFIF</code> node is present in the metadata object,
            the image is converted to sRGB, and then to YCbCr during encoding,
@@ -471,6 +496,8 @@
     </ul>
 
   <li> PhotoYCCA Images:
+       Subject to the <a href=#optcolor>optional library support</a>
+       described above,
     <ul>
       <li> If an <code>app0JFIF</code> node is present in the metadata object,
            it is ignored and a warning is sent to listeners, as JFIF does not
--- a/jdk/src/share/classes/javax/management/loading/package.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/loading/package.html	Wed May 18 13:19:32 2011 +0200
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.loading package</title>
 <!--
-Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 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
@@ -68,7 +68,7 @@
 
     <p id="spec">
     @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java SE 6 Platform documentation on JMX technology</a>,
+      Java Platform documentation on JMX technology</a>,
     in particular the 
     <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
       JMX Specification, version 1.4(pdf).</a>
--- a/jdk/src/share/classes/javax/management/modelmbean/package.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/modelmbean/package.html	Wed May 18 13:19:32 2011 +0200
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.modelmbean package</title>
 <!--
-Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 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
@@ -116,7 +116,7 @@
 	  <li>See the <i>JMX 1.4 Specification</i>
 	     PDF document available from the 
 	     <a href="{@docRoot}/../technotes/guides/jmx/">
-	     Java SE 6 Platform documentation on JMX</a>
+	     Java Platform documentation on JMX technology</a>
     </ul>
 
     @since 1.5
--- a/jdk/src/share/classes/javax/management/monitor/package.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/monitor/package.html	Wed May 18 13:19:32 2011 +0200
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.monitor package</title>
 <!--
-Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 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
@@ -184,7 +184,7 @@
       </ul>
     <p id="spec">
     @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java SE 6 Platform documentation on JMX technology</a>,
+      Java Platform documentation on JMX technology</a>,
     in particular the 
     <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
       JMX Specification, version 1.4(pdf).</a>
--- a/jdk/src/share/classes/javax/management/openmbean/package.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/openmbean/package.html	Wed May 18 13:19:32 2011 +0200
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.openmbean package</title>
 <!--
-Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2001, 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
@@ -143,7 +143,7 @@
     </ul>
 
     @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java SE 6 Platform documentation on JMX technology</a>,
+      Java Platform documentation on JMX technology</a>,
     in particular the 
     <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
       JMX Specification, version 1.4</a>
--- a/jdk/src/share/classes/javax/management/package.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/package.html	Wed May 18 13:19:32 2011 +0200
@@ -2,7 +2,7 @@
     <head>
         <title>javax.management package</title>
         <!--
-Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 1999, 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
@@ -391,7 +391,7 @@
 
         <p id="spec">
         @see <a href="{@docRoot}/../technotes/guides/jmx/index.html">
-        Java SE 6 Platform documentation on JMX technology</a>
+        Java Platform documentation on JMX technology</a>
         in particular the
         <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
         JMX Specification, version 1.4(pdf).</a>
--- a/jdk/src/share/classes/javax/management/relation/package.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/relation/package.html	Wed May 18 13:19:32 2011 +0200
@@ -2,7 +2,7 @@
 <head>
 <title>javax.management.relation package</title>
 <!--
-Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2000, 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
@@ -137,7 +137,7 @@
 </pre>
 
     @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java SE 6 Platform documentation on JMX technology</a>,
+      Java Platform documentation on JMX technology</a>,
     in particular the 
     <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
       JMX Specification, version 1.4</a>
--- a/jdk/src/share/classes/javax/management/remote/package.html	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/remote/package.html	Wed May 18 13:19:32 2011 +0200
@@ -2,7 +2,7 @@
 <head>
     <title>JMX<sup><font size="-2">TM</font></sup> Remote API.</title>
 <!--
-Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2002, 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
@@ -195,7 +195,7 @@
 
 
     @see <a href="{@docRoot}/../technotes/guides/jmx/">
-      Java SE 6 Platform documentation on JMX technology</a>,
+      Java Platform documentation on JMX technology</a>,
     in particular the 
     <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
       JMX Specification, version 1.4</a>
--- a/jdk/src/share/classes/javax/management/timer/Timer.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/management/timer/Timer.java	Wed May 18 13:19:32 2011 +0200
@@ -26,6 +26,7 @@
 package javax.management.timer;
 
 import static com.sun.jmx.defaults.JmxProperties.TIMER_LOGGER;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.Hashtable;
 import java.util.Iterator;
@@ -1003,7 +1004,10 @@
         Integer notifID;
         Date date;
 
-        for (Object[] obj : timerTable.values()) {
+        ArrayList<Object[]> values =
+            new ArrayList<Object[]>(timerTable.values());
+
+        for (Object[] obj : values) {
 
             // Retrieve the timer notification and the date notification.
             //
--- a/jdk/src/share/classes/javax/swing/ComboBoxModel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/ComboBoxModel.java	Wed May 18 13:19:32 2011 +0200
@@ -33,9 +33,11 @@
  * <code>ListModel</code>. This disjoint behavior allows for the temporary
  * storage and retrieval of a selected item in the model.
  *
+ * @param <E> the type of the elements of this model
+ *
  * @author Arnaud Weber
  */
-public interface ComboBoxModel extends ListModel {
+public interface ComboBoxModel<E> extends ListModel<E> {
 
   /**
    * Set the selected item. The implementation of this  method should notify
--- a/jdk/src/share/classes/javax/swing/DefaultComboBoxModel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/DefaultComboBoxModel.java	Wed May 18 13:19:32 2011 +0200
@@ -24,39 +24,28 @@
  */
 package javax.swing;
 
-import java.beans.*;
 import java.util.*;
 
-import java.awt.*;
-import java.awt.event.*;
-
 import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
-
-import javax.swing.event.*;
-import javax.swing.plaf.*;
-import javax.swing.border.*;
-
-import javax.accessibility.*;
 
 /**
  * The default model for combo boxes.
  *
+ * @param <E> the type of the elements of this model
+ *
  * @author Arnaud Weber
  * @author Tom Santos
  */
 
-public class DefaultComboBoxModel extends AbstractListModel implements MutableComboBoxModel, Serializable {
-    Vector objects;
+public class DefaultComboBoxModel<E> extends AbstractListModel<E> implements MutableComboBoxModel<E>, Serializable {
+    Vector<E> objects;
     Object selectedObject;
 
     /**
      * Constructs an empty DefaultComboBoxModel object.
      */
     public DefaultComboBoxModel() {
-        objects = new Vector();
+        objects = new Vector<E>();
     }
 
     /**
@@ -65,8 +54,8 @@
      *
      * @param items  an array of Object objects
      */
-    public DefaultComboBoxModel(final Object items[]) {
-        objects = new Vector();
+    public DefaultComboBoxModel(final E items[]) {
+        objects = new Vector<E>();
         objects.ensureCapacity( items.length );
 
         int i,c;
@@ -84,7 +73,7 @@
      *
      * @param v  a Vector object ...
      */
-    public DefaultComboBoxModel(Vector<?> v) {
+    public DefaultComboBoxModel(Vector<E> v) {
         objects = v;
 
         if ( getSize() > 0 ) {
@@ -117,7 +106,7 @@
     }
 
     // implements javax.swing.ListModel
-    public Object getElementAt(int index) {
+    public E getElementAt(int index) {
         if ( index >= 0 && index < objects.size() )
             return objects.elementAt(index);
         else
@@ -136,7 +125,7 @@
     }
 
     // implements javax.swing.MutableComboBoxModel
-    public void addElement(Object anObject) {
+    public void addElement(E anObject) {
         objects.addElement(anObject);
         fireIntervalAdded(this,objects.size()-1, objects.size()-1);
         if ( objects.size() == 1 && selectedObject == null && anObject != null ) {
@@ -145,7 +134,7 @@
     }
 
     // implements javax.swing.MutableComboBoxModel
-    public void insertElementAt(Object anObject,int index) {
+    public void insertElementAt(E anObject,int index) {
         objects.insertElementAt(anObject,index);
         fireIntervalAdded(this, index, index);
     }
--- a/jdk/src/share/classes/javax/swing/JComboBox.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/JComboBox.java	Wed May 18 13:19:32 2011 +0200
@@ -69,6 +69,8 @@
  * @see ComboBoxModel
  * @see DefaultComboBoxModel
  *
+ * @param <E> the type of the elements of this combo box
+ *
  * @beaninfo
  *   attribute: isContainer false
  * description: A combination of a text field and a drop-down list.
@@ -76,7 +78,7 @@
  * @author Arnaud Weber
  * @author Mark Davidson
  */
-public class JComboBox extends JComponent
+public class JComboBox<E> extends JComponent
 implements ItemSelectable,ListDataListener,ActionListener, Accessible {
     /**
      * @see #getUIClassID
@@ -91,7 +93,7 @@
      * @see #getModel
      * @see #setModel
      */
-    protected ComboBoxModel    dataModel;
+    protected ComboBoxModel<E>    dataModel;
     /**
      * This protected field is implementation specific. Do not access directly
      * or override. Use the accessor methods instead.
@@ -99,7 +101,7 @@
      * @see #getRenderer
      * @see #setRenderer
      */
-    protected ListCellRenderer renderer;
+    protected ListCellRenderer<? super E> renderer;
     /**
      * This protected field is implementation specific. Do not access directly
      * or override. Use the accessor methods instead.
@@ -156,7 +158,7 @@
      */
     protected Object selectedItemReminder = null;
 
-    private Object prototypeDisplayValue;
+    private E prototypeDisplayValue;
 
     // Flag to ensure that infinite loops do not occur with ActionEvents.
     private boolean firingActionEvent = false;
@@ -175,7 +177,7 @@
      *          displayed list of items
      * @see DefaultComboBoxModel
      */
-    public JComboBox(ComboBoxModel aModel) {
+    public JComboBox(ComboBoxModel<E> aModel) {
         super();
         setModel(aModel);
         init();
@@ -189,9 +191,9 @@
      * @param items  an array of objects to insert into the combo box
      * @see DefaultComboBoxModel
      */
-    public JComboBox(final Object items[]) {
+    public JComboBox(E[] items) {
         super();
-        setModel(new DefaultComboBoxModel(items));
+        setModel(new DefaultComboBoxModel<E>(items));
         init();
     }
 
@@ -203,9 +205,9 @@
      * @param items  an array of vectors to insert into the combo box
      * @see DefaultComboBoxModel
      */
-    public JComboBox(Vector<?> items) {
+    public JComboBox(Vector<E> items) {
         super();
-        setModel(new DefaultComboBoxModel(items));
+        setModel(new DefaultComboBoxModel<E>(items));
         init();
     }
 
@@ -219,7 +221,7 @@
      */
     public JComboBox() {
         super();
-        setModel(new DefaultComboBoxModel());
+        setModel(new DefaultComboBoxModel<E>());
         init();
     }
 
@@ -263,7 +265,7 @@
     public void updateUI() {
         setUI((ComboBoxUI)UIManager.getUI(this));
 
-        ListCellRenderer renderer = getRenderer();
+        ListCellRenderer<? super E> renderer = getRenderer();
         if (renderer instanceof Component) {
             SwingUtilities.updateComponentTreeUI((Component)renderer);
         }
@@ -302,8 +304,8 @@
      *        bound: true
      *  description: Model that the combo box uses to get data to display.
      */
-    public void setModel(ComboBoxModel aModel) {
-        ComboBoxModel oldModel = dataModel;
+    public void setModel(ComboBoxModel<E> aModel) {
+        ComboBoxModel<E> oldModel = dataModel;
         if (oldModel != null) {
             oldModel.removeListDataListener(this);
         }
@@ -322,7 +324,7 @@
      * @return the <code>ComboBoxModel</code> that provides the displayed
      *                  list of items
      */
-    public ComboBoxModel getModel() {
+    public ComboBoxModel<E> getModel() {
         return dataModel;
     }
 
@@ -461,8 +463,8 @@
      *     expert: true
      *  description: The renderer that paints the item selected in the list.
      */
-    public void setRenderer(ListCellRenderer aRenderer) {
-        ListCellRenderer oldRenderer = renderer;
+    public void setRenderer(ListCellRenderer<? super E> aRenderer) {
+        ListCellRenderer<? super E> oldRenderer = renderer;
         renderer = aRenderer;
         firePropertyChange( "renderer", oldRenderer, renderer );
         invalidate();
@@ -475,7 +477,7 @@
      * @return  the <code>ListCellRenderer</code> that displays
      *                  the selected item.
      */
-    public ListCellRenderer getRenderer() {
+    public ListCellRenderer<? super E> getRenderer() {
         return renderer;
     }
 
@@ -558,7 +560,7 @@
                 // will be rejected.
                 boolean found = false;
                 for (int i = 0; i < dataModel.getSize(); i++) {
-                    Object element = dataModel.getElementAt(i);
+                    E element = dataModel.getElementAt(i);
                     if (anObject.equals(element)) {
                         found = true;
                         objectToSelect = element;
@@ -640,7 +642,7 @@
     public int getSelectedIndex() {
         Object sObject = dataModel.getSelectedItem();
         int i,c;
-        Object obj;
+        E obj;
 
         for ( i=0,c=dataModel.getSize();i<c;i++ ) {
             obj = dataModel.getElementAt(i);
@@ -658,7 +660,7 @@
      * @see #setPrototypeDisplayValue
      * @since 1.4
      */
-    public Object getPrototypeDisplayValue() {
+    public E getPrototypeDisplayValue() {
         return prototypeDisplayValue;
     }
 
@@ -683,7 +685,7 @@
      *   attribute: visualUpdate true
      * description: The display prototype value, used to compute display width and height.
      */
-    public void setPrototypeDisplayValue(Object prototypeDisplayValue) {
+    public void setPrototypeDisplayValue(E prototypeDisplayValue) {
         Object oldValue = this.prototypeDisplayValue;
         this.prototypeDisplayValue = prototypeDisplayValue;
         firePropertyChange("prototypeDisplayValue", oldValue, prototypeDisplayValue);
@@ -708,12 +710,12 @@
      *   }
      * </pre>
      *
-     * @param anObject the Object to add to the list
+     * @param item the item to add to the list
      * @see MutableComboBoxModel
      */
-    public void addItem(Object anObject) {
+    public void addItem(E item) {
         checkMutableComboBoxModel();
-        ((MutableComboBoxModel)dataModel).addElement(anObject);
+        ((MutableComboBoxModel<E>)dataModel).addElement(item);
     }
 
     /**
@@ -721,14 +723,14 @@
      * This method works only if the <code>JComboBox</code> uses a
      * mutable data model.
      *
-     * @param anObject the <code>Object</code> to add to the list
+     * @param item the item to add to the list
      * @param index    an integer specifying the position at which
      *                  to add the item
      * @see MutableComboBoxModel
      */
-    public void insertItemAt(Object anObject, int index) {
+    public void insertItemAt(E item, int index) {
         checkMutableComboBoxModel();
-        ((MutableComboBoxModel)dataModel).insertElementAt(anObject,index);
+        ((MutableComboBoxModel<E>)dataModel).insertElementAt(item,index);
     }
 
     /**
@@ -756,7 +758,7 @@
      */
     public void removeItemAt(int anIndex) {
         checkMutableComboBoxModel();
-        ((MutableComboBoxModel)dataModel).removeElementAt( anIndex );
+        ((MutableComboBoxModel<E>)dataModel).removeElementAt( anIndex );
     }
 
     /**
@@ -764,7 +766,7 @@
      */
     public void removeAllItems() {
         checkMutableComboBoxModel();
-        MutableComboBoxModel model = (MutableComboBoxModel)dataModel;
+        MutableComboBoxModel<E> model = (MutableComboBoxModel<E>)dataModel;
         int size = model.getSize();
 
         if ( model instanceof DefaultComboBoxModel ) {
@@ -772,7 +774,7 @@
         }
         else {
             for ( int i = 0; i < size; ++i ) {
-                Object element = model.getElementAt( 0 );
+                E element = model.getElementAt( 0 );
                 model.removeElement( element );
             }
         }
@@ -1188,11 +1190,11 @@
 
 
     private static class ComboBoxActionPropertyChangeListener
-                 extends ActionPropertyChangeListener<JComboBox> {
-        ComboBoxActionPropertyChangeListener(JComboBox b, Action a) {
+                 extends ActionPropertyChangeListener<JComboBox<?>> {
+        ComboBoxActionPropertyChangeListener(JComboBox<?> b, Action a) {
             super(b, a);
         }
-        protected void actionPropertyChanged(JComboBox cb,
+        protected void actionPropertyChanged(JComboBox<?> cb,
                                              Action action,
                                              PropertyChangeEvent e) {
             if (AbstractAction.shouldReconfigure(e)) {
@@ -1454,10 +1456,10 @@
      *
      * @param index  an integer indicating the list position, where the first
      *               item starts at zero
-     * @return the <code>Object</code> at that list position; or
+     * @return the item at that list position; or
      *                  <code>null</code> if out of range
      */
-    public Object getItemAt(int index) {
+    public E getItemAt(int index) {
         return dataModel.getElementAt(index);
     }
 
--- a/jdk/src/share/classes/javax/swing/MutableComboBoxModel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/MutableComboBoxModel.java	Wed May 18 13:19:32 2011 +0200
@@ -27,19 +27,21 @@
 /**
  * A mutable version of <code>ComboBoxModel</code>.
  *
+ * @param <E> the type of the elements of this model
+ *
  * @author Tom Santos
  */
 
-public interface MutableComboBoxModel extends ComboBoxModel {
+public interface MutableComboBoxModel<E> extends ComboBoxModel<E> {
 
     /**
      * Adds an item at the end of the model. The implementation of this method
      * should notify all registered <code>ListDataListener</code>s that the
      * item has been added.
      *
-     * @param obj the <code>Object</code> to be added
+     * @param item the item to be added
      */
-    public void addElement( Object obj );
+    public void addElement( E item );
 
     /**
      * Removes an item from the model. The implementation of this method should
@@ -55,17 +57,17 @@
      * should notify all registered <code>ListDataListener</code>s that the
      * item has been added.
      *
-     * @param obj  the <code>Object</code> to be added
+     * @param item  the item to be added
      * @param index  location to add the object
      */
-    public void insertElementAt( Object obj, int index );
+    public void insertElementAt( E item, int index );
 
     /**
      * Removes an item at a specific index. The implementation of this method
      * should notify all registered <code>ListDataListener</code>s that the
      * item has been removed.
      *
-     * @param index  location of object to be removed
+     * @param index  location of the item to be removed
      */
     public void removeElementAt( int index );
 }
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java	Wed May 18 13:19:32 2011 +0200
@@ -40,7 +40,7 @@
  *
  * @author Jeff Dinkins
  */
-public class BasicDirectoryModel extends AbstractListModel implements PropertyChangeListener {
+public class BasicDirectoryModel extends AbstractListModel<Object> implements PropertyChangeListener {
 
     private JFileChooser filechooser = null;
     // PENDING(jeff) pick the size more sensibly
--- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java	Wed May 18 13:19:32 2011 +0200
@@ -906,7 +906,7 @@
     /**
      * Data model for a type-face selection combo-box.
      */
-    protected class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel {
+    protected class DirectoryComboBoxModel extends AbstractListModel<Object> implements ComboBoxModel<Object> {
         Vector<File> directories = new Vector<File>();
         int[] depths = null;
         File selectedDirectory = null;
@@ -1063,7 +1063,7 @@
     /**
      * Data model for a type-face selection combo-box.
      */
-    protected class FilterComboBoxModel extends AbstractListModel implements ComboBoxModel, PropertyChangeListener {
+    protected class FilterComboBoxModel extends AbstractListModel<Object> implements ComboBoxModel<Object>, PropertyChangeListener {
         protected FileFilter[] filters;
         protected FilterComboBoxModel() {
             super();
--- a/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Wed May 18 13:19:32 2011 +0200
@@ -488,6 +488,18 @@
         paintContentBorder(tabContentContext, g, tabPlacement, selectedIndex);
     }
 
+    protected void paintTabArea(Graphics g, int tabPlacement,
+                                int selectedIndex) {
+        // This can be invoked from ScrollabeTabPanel
+        Insets insets = tabPane.getInsets();
+        int x = insets.left;
+        int y = insets.top;
+        int width = tabPane.getWidth() - insets.left - insets.right;
+        int height = tabPane.getHeight() - insets.top - insets.bottom;
+
+        paintTabArea(tabAreaContext, g, tabPlacement, selectedIndex,
+                     new Rectangle(x, y, width, height));
+    }
 
     private void paintTabArea(SynthContext ss, Graphics g,
                                 int tabPlacement, int selectedIndex,
--- a/jdk/src/share/classes/sun/awt/FontDescriptor.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/awt/FontDescriptor.java	Wed May 18 13:19:32 2011 +0200
@@ -26,7 +26,7 @@
 
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetEncoder;
-import java.nio.charset.StandardCharset;
+import java.nio.charset.StandardCharsets;
 import sun.nio.cs.HistoricallyNamedCharset;
 
 public class FontDescriptor implements Cloneable {
@@ -105,8 +105,8 @@
         if (useUnicode && unicodeEncoder == null) {
             try {
                 this.unicodeEncoder = isLE?
-                    StandardCharset.UTF_16LE.newEncoder():
-                    StandardCharset.UTF_16BE.newEncoder();
+                    StandardCharsets.UTF_16LE.newEncoder():
+                    StandardCharsets.UTF_16BE.newEncoder();
             } catch (IllegalArgumentException x) {}
         }
         return useUnicode;
--- a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java	Wed May 18 13:19:32 2011 +0200
@@ -31,10 +31,15 @@
 import java.lang.invoke.MethodType;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.EnumMap;
 import java.util.List;
 
 public class ValueConversions {
+    private static final Class<?> THIS_CLASS = ValueConversions.class;
+    // Do not adjust this except for special platforms:
+    private static final int MAX_ARITY = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
+
     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
 
     private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
@@ -42,88 +47,101 @@
         EnumMap<Wrapper, MethodHandle>[] caches
                 = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n];  // unchecked warning expected here
         for (int i = 0; i < n; i++)
-            caches[i] = new EnumMap<Wrapper, MethodHandle>(Wrapper.class);
+            caches[i] = new EnumMap<>(Wrapper.class);
         return caches;
     }
 
     /// Converting references to values.
 
-    static int unboxInteger(Object x) {
-        if (x == null)  return 0;  // never NPE
-        return ((Integer) x).intValue();
+    // There are several levels of this unboxing conversions:
+    //   no conversions:  exactly Integer.valueOf, etc.
+    //   implicit conversions sanctioned by JLS 5.1.2, etc.
+    //   explicit conversions as allowed by explicitCastArguments
+
+    static int unboxInteger(Object x, boolean cast) {
+        if (x instanceof Integer)
+            return ((Integer) x).intValue();
+        return primitiveConversion(Wrapper.INT, x, cast).intValue();
     }
 
-    static byte unboxByte(Object x) {
-        if (x == null)  return 0;  // never NPE
-        return ((Byte) x).byteValue();
+    static byte unboxByte(Object x, boolean cast) {
+        if (x instanceof Byte)
+            return ((Byte) x).byteValue();
+        return primitiveConversion(Wrapper.BYTE, x, cast).byteValue();
     }
 
-    static short unboxShort(Object x) {
-        if (x == null)  return 0;  // never NPE
-        return ((Short) x).shortValue();
+    static short unboxShort(Object x, boolean cast) {
+        if (x instanceof Short)
+            return ((Short) x).shortValue();
+        return primitiveConversion(Wrapper.SHORT, x, cast).shortValue();
     }
 
-    static boolean unboxBoolean(Object x) {
-        if (x == null)  return false;  // never NPE
-        return ((Boolean) x).booleanValue();
+    static boolean unboxBoolean(Object x, boolean cast) {
+        if (x instanceof Boolean)
+            return ((Boolean) x).booleanValue();
+        return (primitiveConversion(Wrapper.BOOLEAN, x, cast).intValue() & 1) != 0;
     }
 
-    static char unboxCharacter(Object x) {
-        if (x == null)  return 0;  // never NPE
-        return ((Character) x).charValue();
+    static char unboxCharacter(Object x, boolean cast) {
+        if (x instanceof Character)
+            return ((Character) x).charValue();
+        return (char) primitiveConversion(Wrapper.CHAR, x, cast).intValue();
     }
 
-    static long unboxLong(Object x) {
-        if (x == null)  return 0;  // never NPE
-        return ((Long) x).longValue();
+    static long unboxLong(Object x, boolean cast) {
+        if (x instanceof Long)
+            return ((Long) x).longValue();
+        return primitiveConversion(Wrapper.LONG, x, cast).longValue();
     }
 
-    static float unboxFloat(Object x) {
-        if (x == null)  return 0;  // never NPE
-        return ((Float) x).floatValue();
+    static float unboxFloat(Object x, boolean cast) {
+        if (x instanceof Float)
+            return ((Float) x).floatValue();
+        return primitiveConversion(Wrapper.FLOAT, x, cast).floatValue();
     }
 
-    static double unboxDouble(Object x) {
-        if (x == null)  return 0;  // never NPE
-        return ((Double) x).doubleValue();
+    static double unboxDouble(Object x, boolean cast) {
+        if (x instanceof Double)
+            return ((Double) x).doubleValue();
+        return primitiveConversion(Wrapper.DOUBLE, x, cast).doubleValue();
     }
 
     /// Converting references to "raw" values.
     /// A raw primitive value is always an int or long.
 
-    static int unboxByteRaw(Object x) {
-        return unboxByte(x);
+    static int unboxByteRaw(Object x, boolean cast) {
+        return unboxByte(x, cast);
     }
 
-    static int unboxShortRaw(Object x) {
-        return unboxShort(x);
+    static int unboxShortRaw(Object x, boolean cast) {
+        return unboxShort(x, cast);
     }
 
-    static int unboxBooleanRaw(Object x) {
-        return unboxBoolean(x) ? 1 : 0;
+    static int unboxBooleanRaw(Object x, boolean cast) {
+        return unboxBoolean(x, cast) ? 1 : 0;
     }
 
-    static int unboxCharacterRaw(Object x) {
-        return unboxCharacter(x);
+    static int unboxCharacterRaw(Object x, boolean cast) {
+        return unboxCharacter(x, cast);
     }
 
-    static int unboxFloatRaw(Object x) {
-        return Float.floatToIntBits(unboxFloat(x));
+    static int unboxFloatRaw(Object x, boolean cast) {
+        return Float.floatToIntBits(unboxFloat(x, cast));
     }
 
-    static long unboxDoubleRaw(Object x) {
-        return Double.doubleToRawLongBits(unboxDouble(x));
+    static long unboxDoubleRaw(Object x, boolean cast) {
+        return Double.doubleToRawLongBits(unboxDouble(x, cast));
     }
 
     private static MethodType unboxType(Wrapper wrap, boolean raw) {
-        return MethodType.methodType(rawWrapper(wrap, raw).primitiveType(), wrap.wrapperType());
+        return MethodType.methodType(rawWrapper(wrap, raw).primitiveType(), Object.class, boolean.class);
     }
 
     private static final EnumMap<Wrapper, MethodHandle>[]
             UNBOX_CONVERSIONS = newWrapperCaches(4);
 
-    private static MethodHandle unbox(Wrapper wrap, boolean exact, boolean raw) {
-        EnumMap<Wrapper, MethodHandle> cache = UNBOX_CONVERSIONS[(exact?1:0)+(raw?2:0)];
+    private static MethodHandle unbox(Wrapper wrap, boolean raw, boolean cast) {
+        EnumMap<Wrapper, MethodHandle> cache = UNBOX_CONVERSIONS[(cast?1:0)+(raw?2:0)];
         MethodHandle mh = cache.get(wrap);
         if (mh != null) {
             return mh;
@@ -136,7 +154,7 @@
                 mh = raw ? ALWAYS_ZERO : IGNORE; break;
             case INT: case LONG:
                 // these guys don't need separate raw channels
-                if (raw)  mh = unbox(wrap, exact, false);
+                if (raw)  mh = unbox(wrap, false, cast);
                 break;
         }
         if (mh != null) {
@@ -146,37 +164,62 @@
         // look up the method
         String name = "unbox" + wrap.simpleName() + (raw ? "Raw" : "");
         MethodType type = unboxType(wrap, raw);
-        if (!exact) {
-            try {
-                // actually, type is wrong; the Java method takes Object
-                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
-            } catch (ReflectiveOperationException ex) {
-                mh = null;
-            }
-        } else {
-            mh = unbox(wrap, !exact, raw).asType(type);
+        try {
+            mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
+        } catch (ReflectiveOperationException ex) {
+            mh = null;
         }
         if (mh != null) {
+            mh = MethodHandles.insertArguments(mh, 1, cast);
             cache.put(wrap, mh);
             return mh;
         }
-        throw new IllegalArgumentException("cannot find unbox adapter for " + wrap + (raw ? " (raw)" : ""));
+        throw new IllegalArgumentException("cannot find unbox adapter for " + wrap
+                + (cast ? " (cast)" : "") + (raw ? " (raw)" : ""));
+    }
+
+    public static MethodHandle unboxCast(Wrapper type) {
+        return unbox(type, false, true);
     }
 
-    public static MethodHandle unbox(Wrapper type, boolean exact) {
-        return unbox(type, exact, false);
+    public static MethodHandle unboxRaw(Wrapper type) {
+        return unbox(type, true, false);
+    }
+
+    public static MethodHandle unbox(Class<?> type) {
+        return unbox(Wrapper.forPrimitiveType(type), false, false);
+    }
+
+    public static MethodHandle unboxCast(Class<?> type) {
+        return unbox(Wrapper.forPrimitiveType(type), false, true);
     }
 
-    public static MethodHandle unboxRaw(Wrapper type, boolean exact) {
-        return unbox(type, exact, true);
+    public static MethodHandle unboxRaw(Class<?> type) {
+        return unbox(Wrapper.forPrimitiveType(type), true, false);
     }
 
-    public static MethodHandle unbox(Class<?> type, boolean exact) {
-        return unbox(Wrapper.forPrimitiveType(type), exact, false);
-    }
-
-    public static MethodHandle unboxRaw(Class<?> type, boolean exact) {
-        return unbox(Wrapper.forPrimitiveType(type), exact, true);
+    /// Primitive conversions
+    public static Number primitiveConversion(Wrapper wrap, Object x, boolean cast) {
+        // Maybe merge this code with Wrapper.convert/cast.
+        Number res = null;
+        if (x == null) {
+            if (!cast)  return null;
+            x = wrap.zero();
+        }
+        if (x instanceof Number) {
+            res = (Number) x;
+        } else if (x instanceof Boolean) {
+            res = ((boolean)x ? 1 : 0);
+        } else if (x instanceof Character) {
+            res = (int)(char)x;
+        } else {
+            // this will fail with the required ClassCastException:
+            res = (Number) x;
+        }
+        if (!cast && !wrap.isConvertibleFrom(Wrapper.forWrapperType(x.getClass())))
+            // this will fail with the required ClassCastException:
+            res = (Number) wrap.wrapperType().cast(x);
+        return res;
     }
 
     /// Converting primitives to references
@@ -285,7 +328,7 @@
         MethodType type = boxType(wrap, raw);
         if (exact) {
             try {
-                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
+                mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
             } catch (ReflectiveOperationException ex) {
                 mh = null;
             }
@@ -296,22 +339,31 @@
             cache.put(wrap, mh);
             return mh;
         }
-        throw new IllegalArgumentException("cannot find box adapter for " + wrap + (raw ? " (raw)" : ""));
+        throw new IllegalArgumentException("cannot find box adapter for "
+                + wrap + (exact ? " (exact)" : "") + (raw ? " (raw)" : ""));
     }
 
-    public static MethodHandle box(Class<?> type, boolean exact) {
+    public static MethodHandle box(Class<?> type) {
+        boolean exact = false;
+        // e.g., boxShort(short)Short if exact,
+        // e.g., boxShort(short)Object if !exact
         return box(Wrapper.forPrimitiveType(type), exact, false);
     }
 
-    public static MethodHandle boxRaw(Class<?> type, boolean exact) {
+    public static MethodHandle boxRaw(Class<?> type) {
+        boolean exact = false;
+        // e.g., boxShortRaw(int)Short if exact
+        // e.g., boxShortRaw(int)Object if !exact
         return box(Wrapper.forPrimitiveType(type), exact, true);
     }
 
-    public static MethodHandle box(Wrapper type, boolean exact) {
+    public static MethodHandle box(Wrapper type) {
+        boolean exact = false;
         return box(type, exact, false);
     }
 
-    public static MethodHandle boxRaw(Wrapper type, boolean exact) {
+    public static MethodHandle boxRaw(Wrapper type) {
+        boolean exact = false;
         return box(type, exact, true);
     }
 
@@ -319,16 +371,16 @@
 
     static int unboxRawInteger(Object x) {
         if (x instanceof Integer)
-            return unboxInteger(x);
+            return (int) x;
         else
-            return (int) unboxLong(x);
+            return (int) unboxLong(x, false);
     }
 
     static Integer reboxRawInteger(Object x) {
         if (x instanceof Integer)
             return (Integer) x;
         else
-            return (int) unboxLong(x);
+            return (int) unboxLong(x, false);
     }
 
     static Byte reboxRawByte(Object x) {
@@ -362,7 +414,7 @@
 
     static Double reboxRawDouble(Object x) {
         if (x instanceof Double)  return (Double) x;
-        return boxDoubleRaw(unboxLong(x));
+        return boxDoubleRaw(unboxLong(x, true));
     }
 
     private static MethodType reboxType(Wrapper wrap) {
@@ -371,7 +423,7 @@
     }
 
     private static final EnumMap<Wrapper, MethodHandle>[]
-            REBOX_CONVERSIONS = newWrapperCaches(2);
+            REBOX_CONVERSIONS = newWrapperCaches(1);
 
     /**
      * Because we normalize primitive types to reduce the number of signatures,
@@ -380,10 +432,10 @@
      * When the erased primitive value is then boxed into an Integer or Long,
      * the final boxed primitive is sometimes required.  This transformation
      * is called a "rebox".  It takes an Integer or Long and produces some
-     * other boxed value.
+     * other boxed value, typed (inexactly) as an Object
      */
-    public static MethodHandle rebox(Wrapper wrap, boolean exact) {
-        EnumMap<Wrapper, MethodHandle> cache = REBOX_CONVERSIONS[exact?1:0];
+    public static MethodHandle rebox(Wrapper wrap) {
+        EnumMap<Wrapper, MethodHandle> cache = REBOX_CONVERSIONS[0];
         MethodHandle mh = cache.get(wrap);
         if (mh != null) {
             return mh;
@@ -402,14 +454,11 @@
         // look up the method
         String name = "reboxRaw" + wrap.simpleName();
         MethodType type = reboxType(wrap);
-        if (exact) {
-            try {
-                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
-            } catch (ReflectiveOperationException ex) {
-                mh = null;
-            }
-        } else {
-            mh = rebox(wrap, !exact).asType(IDENTITY.type());
+        try {
+            mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
+            mh = mh.asType(IDENTITY.type());
+        } catch (ReflectiveOperationException ex) {
+            mh = null;
         }
         if (mh != null) {
             cache.put(wrap, mh);
@@ -418,8 +467,8 @@
         throw new IllegalArgumentException("cannot find rebox adapter for " + wrap);
     }
 
-    public static MethodHandle rebox(Class<?> type, boolean exact) {
-        return rebox(Wrapper.forPrimitiveType(type), exact);
+    public static MethodHandle rebox(Class<?> type) {
+        return rebox(Wrapper.forPrimitiveType(type));
     }
 
     /// Width-changing conversions between int and long.
@@ -486,9 +535,10 @@
             case VOID:
                 mh = EMPTY;
                 break;
+            case OBJECT:
             case INT: case LONG: case FLOAT: case DOUBLE:
                 try {
-                    mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "zero"+wrap.simpleName(), type);
+                    mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.simpleName(), type);
                 } catch (ReflectiveOperationException ex) {
                     mh = null;
                 }
@@ -592,7 +642,7 @@
         return t.cast(x);
     }
 
-    private static final MethodHandle IDENTITY, IDENTITY_I, IDENTITY_J, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY;
+    private static final MethodHandle IDENTITY, IDENTITY_I, IDENTITY_J, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY, NEW_ARRAY;
     static {
         try {
             MethodType idType = MethodType.genericMethodType(1);
@@ -600,40 +650,56 @@
             MethodType alwaysZeroType = idType.changeReturnType(int.class);
             MethodType ignoreType = idType.changeReturnType(void.class);
             MethodType zeroObjectType = MethodType.genericMethodType(0);
-            IDENTITY = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", idType);
-            IDENTITY_I = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", MethodType.methodType(int.class, int.class));
-            IDENTITY_J = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", MethodType.methodType(long.class, long.class));
+            IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
+            IDENTITY_I = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(int.class, int.class));
+            IDENTITY_J = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(long.class, long.class));
             //CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
-            CAST_REFERENCE = IMPL_LOOKUP.findStatic(ValueConversions.class, "castReference", castType);
-            ALWAYS_NULL = IMPL_LOOKUP.findStatic(ValueConversions.class, "alwaysNull", idType);
-            ALWAYS_ZERO = IMPL_LOOKUP.findStatic(ValueConversions.class, "alwaysZero", alwaysZeroType);
-            ZERO_OBJECT = IMPL_LOOKUP.findStatic(ValueConversions.class, "zeroObject", zeroObjectType);
-            IGNORE = IMPL_LOOKUP.findStatic(ValueConversions.class, "ignore", ignoreType);
-            EMPTY = IMPL_LOOKUP.findStatic(ValueConversions.class, "empty", ignoreType.dropParameterTypes(0, 1));
-        } catch (Exception ex) {
+            CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType);
+            ALWAYS_NULL = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysNull", idType);
+            ALWAYS_ZERO = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysZero", alwaysZeroType);
+            ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
+            IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
+            EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
+            NEW_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "newArray", MethodType.methodType(Object[].class, int.class));
+        } catch (NoSuchMethodException | IllegalAccessException ex) {
             Error err = new InternalError("uncaught exception");
             err.initCause(ex);
             throw err;
         }
     }
 
-    private static final EnumMap<Wrapper, MethodHandle> WRAPPER_CASTS
-            = new EnumMap<Wrapper, MethodHandle>(Wrapper.class);
+    // Varargs methods need to be in a separately initialized class, to bootstrapping problems.
+    static class LazyStatics {
+        private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
+        static {
+            try {
+                //MAKE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeArray", MethodType.methodType(Object[].class, Object[].class));
+                COPY_AS_REFERENCE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsReferenceArray", MethodType.methodType(Object[].class, Class.class, Object[].class));
+                COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class));
+                MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class));
+            } catch (ReflectiveOperationException ex) {
+                Error err = new InternalError("uncaught exception");
+                err.initCause(ex);
+                throw err;
+            }
+        }
+    }
 
-    private static final EnumMap<Wrapper, MethodHandle> EXACT_WRAPPER_CASTS
-            = new EnumMap<Wrapper, MethodHandle>(Wrapper.class);
+    private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
+            = newWrapperCaches(2);
 
     /** Return a method that casts its sole argument (an Object) to the given type
      *  and returns it as the given type (if exact is true), or as plain Object (if erase is true).
      */
-    public static MethodHandle cast(Class<?> type, boolean exact) {
+    public static MethodHandle cast(Class<?> type) {
+        boolean exact = false;
         if (type.isPrimitive())  throw new IllegalArgumentException("cannot cast primitive type "+type);
         MethodHandle mh = null;
         Wrapper wrap = null;
         EnumMap<Wrapper, MethodHandle> cache = null;
         if (Wrapper.isWrapperType(type)) {
             wrap = Wrapper.forWrapperType(type);
-            cache = (exact ? EXACT_WRAPPER_CASTS : WRAPPER_CASTS);
+            cache = WRAPPER_CASTS[exact?1:0];
             mh = cache.get(wrap);
             if (mh != null)  return mh;
         }
@@ -673,7 +739,7 @@
         if (wrap != Wrapper.VOID)
             type = type.appendParameterTypes(wrap.primitiveType());
         try {
-            mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "identity", type);
+            mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", type);
         } catch (ReflectiveOperationException ex) {
             mh = null;
         }
@@ -692,6 +758,210 @@
         throw new IllegalArgumentException("cannot find identity for " + wrap);
     }
 
+    /// Float/non-float conversions.
+
+    static float doubleToFloat(double x) {
+        return (float) x;
+    }
+    static double floatToDouble(float x) {
+        return x;
+    }
+
+    // narrow double to integral type
+    static long doubleToLong(double x) {
+        return (long) x;
+    }
+    static int doubleToInt(double x) {
+        return (int) x;
+    }
+    static short doubleToShort(double x) {
+        return (short) x;
+    }
+    static char doubleToChar(double x) {
+        return (char) x;
+    }
+    static byte doubleToByte(double x) {
+        return (byte) x;
+    }
+    static boolean doubleToBoolean(double x) {
+        return toBoolean((byte) x);
+    }
+
+    // narrow float to integral type
+    static long floatToLong(float x) {
+        return (long) x;
+    }
+    static int floatToInt(float x) {
+        return (int) x;
+    }
+    static short floatToShort(float x) {
+        return (short) x;
+    }
+    static char floatToChar(float x) {
+        return (char) x;
+    }
+    static byte floatToByte(float x) {
+        return (byte) x;
+    }
+    static boolean floatToBoolean(float x) {
+        return toBoolean((byte) x);
+    }
+
+    // widen integral type to double
+    static double longToDouble(long x) {
+        return x;
+    }
+    static double intToDouble(int x) {
+        return x;
+    }
+    static double shortToDouble(short x) {
+        return x;
+    }
+    static double charToDouble(char x) {
+        return x;
+    }
+    static double byteToDouble(byte x) {
+        return x;
+    }
+    static double booleanToDouble(boolean x) {
+        return fromBoolean(x);
+    }
+
+    // widen integral type to float
+    static float longToFloat(long x) {
+        return x;
+    }
+    static float intToFloat(int x) {
+        return x;
+    }
+    static float shortToFloat(short x) {
+        return x;
+    }
+    static float charToFloat(char x) {
+        return x;
+    }
+    static float byteToFloat(byte x) {
+        return x;
+    }
+    static float booleanToFloat(boolean x) {
+        return fromBoolean(x);
+    }
+
+    static boolean toBoolean(byte x) {
+        // see javadoc for MethodHandles.explicitCastArguments
+        return ((x & 1) != 0);
+    }
+    static byte fromBoolean(boolean x) {
+        // see javadoc for MethodHandles.explicitCastArguments
+        return (x ? (byte)1 : (byte)0);
+    }
+
+    private static final EnumMap<Wrapper, MethodHandle>[]
+            CONVERT_FLOAT_FUNCTIONS = newWrapperCaches(4);
+
+    static MethodHandle convertFloatFunction(Wrapper wrap, boolean toFloat, boolean doubleSize) {
+        EnumMap<Wrapper, MethodHandle> cache = CONVERT_FLOAT_FUNCTIONS[(toFloat?1:0)+(doubleSize?2:0)];
+        MethodHandle mh = cache.get(wrap);
+        if (mh != null) {
+            return mh;
+        }
+        // slow path
+        Wrapper fwrap = (doubleSize ? Wrapper.DOUBLE : Wrapper.FLOAT);
+        Class<?> fix = wrap.primitiveType();
+        Class<?> flt = (doubleSize ? double.class : float.class);
+        Class<?> src = toFloat ? fix : flt;
+        Class<?> dst = toFloat ? flt : fix;
+        if (src == dst)  return identity(wrap);
+        MethodType type = MethodType.methodType(dst, src);
+        switch (wrap) {
+            case VOID:
+                mh = toFloat ? zeroConstantFunction(fwrap) : MethodHandles.dropArguments(EMPTY, 0, flt);
+                break;
+            case OBJECT:
+                mh = toFloat ? unbox(flt) : box(flt);
+                break;
+            default:
+                try {
+                    mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type);
+                } catch (ReflectiveOperationException ex) {
+                    mh = null;
+                }
+                break;
+        }
+        if (mh != null) {
+            assert(mh.type() == type) : mh;
+            cache.put(wrap, mh);
+            return mh;
+        }
+
+        throw new IllegalArgumentException("cannot find float conversion constant for " +
+                                           src.getSimpleName()+" -> "+dst.getSimpleName());
+    }
+
+    public static MethodHandle convertFromFloat(Class<?> fixType) {
+        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
+        return convertFloatFunction(wrap, false, false);
+    }
+    public static MethodHandle convertFromDouble(Class<?> fixType) {
+        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
+        return convertFloatFunction(wrap, false, true);
+    }
+    public static MethodHandle convertToFloat(Class<?> fixType) {
+        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
+        return convertFloatFunction(wrap, true, false);
+    }
+    public static MethodHandle convertToDouble(Class<?> fixType) {
+        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
+        return convertFloatFunction(wrap, true, true);
+    }
+
+    private static String capitalize(String x) {
+        return Character.toUpperCase(x.charAt(0))+x.substring(1);
+    }
+
+    /// Collection of multiple arguments.
+
+    public static Object convertArrayElements(Class<?> arrayType, Object array) {
+        Class<?> src = array.getClass().getComponentType();
+        Class<?> dst = arrayType.getComponentType();
+        if (src == null || dst == null)  throw new IllegalArgumentException("not array type");
+        Wrapper sw = (src.isPrimitive() ? Wrapper.forPrimitiveType(src) : null);
+        Wrapper dw = (dst.isPrimitive() ? Wrapper.forPrimitiveType(dst) : null);
+        int length;
+        if (sw == null) {
+            Object[] a = (Object[]) array;
+            length = a.length;
+            if (dw == null)
+                return Arrays.copyOf(a, length, arrayType.asSubclass(Object[].class));
+            Object res = dw.makeArray(length);
+            dw.copyArrayUnboxing(a, 0, res, 0, length);
+            return res;
+        }
+        length = java.lang.reflect.Array.getLength(array);
+        Object[] res;
+        if (dw == null) {
+            res = Arrays.copyOf(NO_ARGS_ARRAY, length, arrayType.asSubclass(Object[].class));
+        } else {
+            res = new Object[length];
+        }
+        sw.copyArrayBoxing(array, 0, res, 0, length);
+        if (dw == null)  return res;
+        Object a = dw.makeArray(length);
+        dw.copyArrayUnboxing(res, 0, a, 0, length);
+        return a;
+    }
+
+    private static MethodHandle findCollector(String name, int nargs, Class<?> rtype, Class<?>... ptypes) {
+        MethodType type = MethodType.genericMethodType(nargs)
+                .changeReturnType(rtype)
+                .insertParameterTypes(0, ptypes);
+        try {
+            return IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
+        } catch (ReflectiveOperationException ex) {
+            return null;
+        }
+    }
+
     private static final Object[] NO_ARGS_ARRAY = {};
     private static Object[] makeArray(Object... args) { return args; }
     private static Object[] array() { return NO_ARGS_ARRAY; }
@@ -723,35 +993,175 @@
                                   Object a4, Object a5, Object a6, Object a7,
                                   Object a8, Object a9)
                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-    static MethodHandle[] makeArrays() {
-        ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
-        MethodHandles.Lookup lookup = IMPL_LOOKUP;
+    private static MethodHandle[] makeArrays() {
+        ArrayList<MethodHandle> mhs = new ArrayList<>();
         for (;;) {
-            int nargs = arrays.size();
-            MethodType type = MethodType.genericMethodType(nargs).changeReturnType(Object[].class);
-            String name = "array";
-            MethodHandle array = null;
-            try {
-                array = lookup.findStatic(ValueConversions.class, name, type);
-            } catch (ReflectiveOperationException ex) {
-            }
-            if (array == null)  break;
-            arrays.add(array);
+            MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
+            if (mh == null)  break;
+            mhs.add(mh);
         }
-        assert(arrays.size() == 11);  // current number of methods
-        return arrays.toArray(new MethodHandle[0]);
+        assert(mhs.size() == 11);  // current number of methods
+        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
+    }
+    private static final MethodHandle[] ARRAYS = makeArrays();
+
+    // mh-fill versions of the above:
+    private static Object[] newArray(int len) { return new Object[len]; }
+    private static void fillWithArguments(Object[] a, int pos, Object... args) {
+        System.arraycopy(args, 0, a, pos, args.length);
     }
-    static final MethodHandle[] ARRAYS = makeArrays();
+    // using Integer pos instead of int pos to avoid bootstrapping problems
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0)
+                { fillWithArguments(a, pos, a0); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1)
+                { fillWithArguments(a, pos, a0, a1); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2)
+                { fillWithArguments(a, pos, a0, a1, a2); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3)
+                { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+                                  Object a4)
+                { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5)
+                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6)
+                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6, Object a7)
+                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6, Object a7,
+                                  Object a8)
+                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
+    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6, Object a7,
+                                  Object a8, Object a9)
+                { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
+    private static MethodHandle[] makeFillArrays() {
+        ArrayList<MethodHandle> mhs = new ArrayList<>();
+        mhs.add(null);  // there is no empty fill; at least a0 is required
+        for (;;) {
+            MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Object[].class, Integer.class);
+            if (mh == null)  break;
+            mhs.add(mh);
+        }
+        assert(mhs.size() == 11);  // current number of methods
+        return mhs.toArray(new MethodHandle[0]);
+    }
+    private static final MethodHandle[] FILL_ARRAYS = makeFillArrays();
+
+    private static Object[] copyAsReferenceArray(Class<? extends Object[]> arrayType, Object... a) {
+        return Arrays.copyOf(a, a.length, arrayType);
+    }
+    private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
+        Object a = w.makeArray(boxes.length);
+        w.copyArrayUnboxing(boxes, 0, a, 0, boxes.length);
+        return a;
+    }
 
     /** Return a method handle that takes the indicated number of Object
      *  arguments and returns an Object array of them, as if for varargs.
      */
     public static MethodHandle varargsArray(int nargs) {
-        if (nargs < ARRAYS.length)
-            return ARRAYS[nargs];
-        // else need to spin bytecode or do something else fancy
-        throw new UnsupportedOperationException("NYI: cannot form a varargs array of length "+nargs);
+        MethodHandle mh = ARRAYS[nargs];
+        if (mh != null)  return mh;
+        mh = findCollector("array", nargs, Object[].class);
+        if (mh != null)  return ARRAYS[nargs] = mh;
+        MethodHandle producer = filler(0);  // identity function produces result
+        return ARRAYS[nargs] = buildVarargsArray(producer, nargs);
+    }
+
+    private static MethodHandle buildVarargsArray(MethodHandle producer, int nargs) {
+        // Build up the result mh as a sequence of fills like this:
+        //   producer(fill(fill(fill(newArray(23),0,x1..x10),10,x11..x20),20,x21..x23))
+        // The various fill(_,10*I,___*[J]) are reusable.
+        MethodHandle filler = filler(nargs);
+        MethodHandle mh = producer;
+        mh = MethodHandles.dropArguments(mh, 1, filler.type().parameterList());
+        mh = MethodHandles.foldArguments(mh, filler);
+        mh = MethodHandles.foldArguments(mh, buildNewArray(nargs));
+        return mh;
+    }
+
+    private static MethodHandle buildNewArray(int nargs) {
+        return MethodHandles.insertArguments(NEW_ARRAY, 0, (int) nargs);
+    }
+
+    private static final MethodHandle[] FILLERS = new MethodHandle[MAX_ARITY+1];
+    // filler(N).invoke(a, arg0..arg[N-1]) fills a[0]..a[N-1]
+    private static MethodHandle filler(int nargs) {
+        MethodHandle filler = FILLERS[nargs];
+        if (filler != null)  return filler;
+        return FILLERS[nargs] = buildFiller(nargs);
     }
+    private static MethodHandle buildFiller(int nargs) {
+        if (nargs == 0)
+            return MethodHandles.identity(Object[].class);
+        final int CHUNK = (FILL_ARRAYS.length - 1);
+        int rightLen = nargs % CHUNK;
+        int leftLen = nargs - rightLen;
+        if (rightLen == 0) {
+            leftLen = nargs - (rightLen = CHUNK);
+            if (FILLERS[leftLen] == null) {
+                // build some precursors from left to right
+                for (int j = 0; j < leftLen; j += CHUNK)  filler(j);
+            }
+        }
+        MethodHandle leftFill = filler(leftLen);  // recursive fill
+        MethodHandle rightFill = FILL_ARRAYS[rightLen];
+        rightFill = MethodHandles.insertArguments(rightFill, 1, (int) leftLen);  // [leftLen..nargs-1]
+
+        // Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
+        MethodHandle mh = filler(0);  // identity function produces result
+        mh = MethodHandles.dropArguments(mh, 1, rightFill.type().parameterList());
+        mh = MethodHandles.foldArguments(mh, rightFill);
+        if (leftLen > 0) {
+            mh = MethodHandles.dropArguments(mh, 1, leftFill.type().parameterList());
+            mh = MethodHandles.foldArguments(mh, leftFill);
+        }
+        return mh;
+    }
+
+    // Type-polymorphic version of varargs maker.
+    private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
+        = new ClassValue<MethodHandle[]>() {
+            protected MethodHandle[] computeValue(Class<?> type) {
+                return new MethodHandle[256];
+            }
+    };
+
+    /** Return a method handle that takes the indicated number of
+     *  typed arguments and returns an array of them.
+     *  The type argument is the array type.
+     */
+    public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
+        Class<?> elemType = arrayType.getComponentType();
+        if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
+        // FIXME: Need more special casing and caching here.
+        if (elemType == Object.class)
+            return varargsArray(nargs);
+        // other cases:  primitive arrays, subtypes of Object[]
+        MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
+        MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
+        if (mh != null)  return mh;
+        MethodHandle producer = buildArrayProducer(arrayType);
+        mh = buildVarargsArray(producer, nargs);
+        mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
+        cache[nargs] = mh;
+        return mh;
+    }
+
+    private static MethodHandle buildArrayProducer(Class<?> arrayType) {
+        Class<?> elemType = arrayType.getComponentType();
+        if (elemType.isPrimitive())
+            return LazyStatics.COPY_AS_PRIMITIVE_ARRAY.bindTo(Wrapper.forPrimitiveType(elemType));
+        else
+            return LazyStatics.COPY_AS_REFERENCE_ARRAY.bindTo(arrayType);
+    }
+
+    // List version of varargs maker.
 
     private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
     private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
@@ -784,34 +1194,29 @@
                                      Object a4, Object a5, Object a6, Object a7,
                                      Object a8, Object a9)
                 { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-    static MethodHandle[] makeLists() {
-        ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
-        MethodHandles.Lookup lookup = IMPL_LOOKUP;
+    private static MethodHandle[] makeLists() {
+        ArrayList<MethodHandle> mhs = new ArrayList<>();
         for (;;) {
-            int nargs = arrays.size();
-            MethodType type = MethodType.genericMethodType(nargs).changeReturnType(List.class);
-            String name = "list";
-            MethodHandle array = null;
-            try {
-                array = lookup.findStatic(ValueConversions.class, name, type);
-            } catch (ReflectiveOperationException ex) {
-            }
-            if (array == null)  break;
-            arrays.add(array);
+            MethodHandle mh = findCollector("list", mhs.size(), List.class);
+            if (mh == null)  break;
+            mhs.add(mh);
         }
-        assert(arrays.size() == 11);  // current number of methods
-        return arrays.toArray(new MethodHandle[0]);
+        assert(mhs.size() == 11);  // current number of methods
+        return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
     }
-    static final MethodHandle[] LISTS = makeLists();
+    private static final MethodHandle[] LISTS = makeLists();
 
     /** Return a method handle that takes the indicated number of Object
-     *  arguments and returns List.
+     *  arguments and returns a List.
      */
     public static MethodHandle varargsList(int nargs) {
-        if (nargs < LISTS.length)
-            return LISTS[nargs];
-        // else need to spin bytecode or do something else fancy
-        throw new UnsupportedOperationException("NYI");
+        MethodHandle mh = LISTS[nargs];
+        if (mh != null)  return mh;
+        mh = findCollector("list", nargs, List.class);
+        if (mh != null)  return LISTS[nargs] = mh;
+        return LISTS[nargs] = buildVarargsList(nargs);
+    }
+    private static MethodHandle buildVarargsList(int nargs) {
+        return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST);
     }
 }
-
--- a/jdk/src/share/classes/sun/invoke/util/VerifyType.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/invoke/util/VerifyType.java	Wed May 18 13:19:32 2011 +0200
@@ -54,9 +54,15 @@
         if (dst == void.class)     return true;  // drop any return value
         if (isNullType(src))       return !dst.isPrimitive();
         if (!src.isPrimitive())    return dst.isAssignableFrom(src);
+        if (!dst.isPrimitive())    return false;
         // Verifier allows an int to carry byte, short, char, or even boolean:
-        if (dst == int.class)      return Wrapper.forPrimitiveType(src).isSubwordOrInt();
-        return false;
+        Wrapper sw = Wrapper.forPrimitiveType(src);
+        if (dst == int.class)      return sw.isSubwordOrInt();
+        Wrapper dw = Wrapper.forPrimitiveType(dst);
+        if (!sw.isSubwordOrInt())  return false;
+        if (!dw.isSubwordOrInt())  return false;
+        if (!dw.isSigned() && sw.isSigned())  return false;
+        return dw.bitWidth() > sw.bitWidth();
     }
 
     /**
@@ -155,6 +161,7 @@
                     return -1;   // truncation may be required
                 if (!dw.isSigned() && sw.isSigned())
                     return -1;   // sign elimination may be required
+                return 1;
             }
             if (src == float.class || dst == float.class) {
                 if (src == double.class || dst == double.class)
--- a/jdk/src/share/classes/sun/invoke/util/Wrapper.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/invoke/util/Wrapper.java	Wed May 18 13:19:32 2011 +0200
@@ -26,37 +26,47 @@
 package sun.invoke.util;
 
 public enum Wrapper {
-    BOOLEAN(Boolean.class, boolean.class, 'Z', (Boolean)false, Format.unsigned(1)),
+    BOOLEAN(Boolean.class, boolean.class, 'Z', (Boolean)false, new boolean[0], Format.unsigned(1)),
     // These must be in the order defined for widening primitive conversions in JLS 5.1.2
-    BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, Format.signed(8)),
-    SHORT(Short.class, short.class, 'S', (Short)(short)0, Format.signed(16)),
-    CHAR(Character.class, char.class, 'C', (Character)(char)0, Format.unsigned(16)),
-    INT(Integer.class, int.class, 'I', (Integer)(int)0, Format.signed(32)),
-    LONG(Long.class, long.class, 'J', (Long)(long)0, Format.signed(64)),
-    FLOAT(Float.class, float.class, 'F', (Float)(float)0, Format.floating(32)),
-    DOUBLE(Double.class, double.class, 'D', (Double)(double)0, Format.floating(64)),
-    //NULL(Null.class, null.class, 'N', null, Format.other(1)),
-    OBJECT(Object.class, Object.class, 'L', null, Format.other(1)),
+    BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed(8)),
+    SHORT(Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed(16)),
+    CHAR(Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
+    INT(Integer.class, int.class, 'I', (Integer)(int)0, new int[0], Format.signed(32)),
+    LONG(Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed(64)),
+    FLOAT(Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
+    DOUBLE(Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
+    //NULL(Null.class, null.class, 'N', null, null, Format.other(1)),
+    OBJECT(Object.class, Object.class, 'L', null, new Object[0], Format.other(1)),
     // VOID must be the last type, since it is "assignable" from any other type:
-    VOID(Void.class, void.class, 'V', null, Format.other(0)),
+    VOID(Void.class, void.class, 'V', null, null, Format.other(0)),
     ;
 
     private final Class<?> wrapperType;
     private final Class<?> primitiveType;
     private final char     basicTypeChar;
     private final Object   zero;
+    private final Object   emptyArray;
     private final int      format;
     private final String   simpleName;
 
-    private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object zero, int format) {
+    private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object zero, Object emptyArray, int format) {
         this.wrapperType = wtype;
         this.primitiveType = ptype;
         this.basicTypeChar = tchar;
         this.zero = zero;
+        this.emptyArray = emptyArray;
         this.format = format;
         this.simpleName = wtype.getSimpleName();
     }
 
+    /** For debugging, give the details of this wrapper. */
+    public String detailString() {
+        return simpleName+
+                java.util.Arrays.asList(wrapperType, primitiveType,
+                basicTypeChar, zero,
+                "0x"+Integer.toHexString(format));
+    }
+
     private static abstract class Format {
         static final int SLOT_SHIFT = 0, SIZE_SHIFT = 2, KIND_SHIFT = 12;
         static final int
@@ -114,16 +124,18 @@
     public boolean isUnsigned()    { return format >= Format.BOOLEAN && format < Format.FLOAT; }
     /** Is the wrapped type either float or double? */
     public boolean isFloating()    { return format >= Format.FLOAT; }
+    /** Is the wrapped type either void or a reference? */
+    public boolean isOther()       { return (format & ~Format.SLOT_MASK) == 0; }
 
-    /** Does the JVM verifier allow a variable of this wrapper's
+    /** Does the JLS 5.1.2 allow a variable of this wrapper's
      *  primitive type to be assigned from a value of the given wrapper's primitive type?
      *  Cases:
      *  <ul>
      *  <li>unboxing followed by widening primitive conversion
-     *  <li>any type converted to {@code void}
+     *  <li>any type converted to {@code void} (i.e., dropping a method call's value)
      *  <li>boxing conversion followed by widening reference conversion to {@code Object}
-     *  <li>conversion of {@code boolean} to any type
      *  </ul>
+     *  These are the cases allowed by MethodHandle.asType and convertArguments.
      */
     public boolean isConvertibleFrom(Wrapper source) {
         if (this == source)  return true;
@@ -131,13 +143,75 @@
             // At best, this is a narrowing conversion.
             return false;
         }
-        if ((this.format ^ source.format) == (Format.SHORT ^ Format.CHAR)) {
-            assert (this == SHORT && source == CHAR) || (this == CHAR && source == SHORT);
+        // All conversions are allowed in the enum order between floats and signed ints.
+        // First detect non-signed non-float types (boolean, char, Object, void).
+        boolean floatOrSigned = (((this.format & source.format) & Format.SIGNED) != 0);
+        if (!floatOrSigned) {
+            if (this.isOther())  return true;
+            // can convert char to int or wider, but nothing else
+            if (source.format == Format.CHAR)  return true;
+            // no other conversions are classified as widening
             return false;
         }
+        // All signed and float conversions in the enum order are widening.
+        assert(this.isFloating() || this.isSigned());
+        assert(source.isFloating() || source.isSigned());
         return true;
     }
 
+    static { assert(checkConvertibleFrom()); }
+    private static boolean checkConvertibleFrom() {
+        // Check the matrix for correct classification of widening conversions.
+        for (Wrapper w : values()) {
+            assert(w.isConvertibleFrom(w));
+            assert(VOID.isConvertibleFrom(w));
+            if (w != VOID) {
+                assert(OBJECT.isConvertibleFrom(w));
+                assert(!w.isConvertibleFrom(VOID));
+            }
+            // check relations with unsigned integral types:
+            if (w != CHAR) {
+                assert(!CHAR.isConvertibleFrom(w));
+                if (!w.isConvertibleFrom(INT))
+                    assert(!w.isConvertibleFrom(CHAR));
+            }
+            if (w != BOOLEAN) {
+                assert(!BOOLEAN.isConvertibleFrom(w));
+                if (w != VOID && w != OBJECT)
+                    assert(!w.isConvertibleFrom(BOOLEAN));
+            }
+            // check relations with signed integral types:
+            if (w.isSigned()) {
+                for (Wrapper x : values()) {
+                    if (w == x)  continue;
+                    if (x.isFloating())
+                        assert(!w.isConvertibleFrom(x));
+                    else if (x.isSigned()) {
+                        if (w.compareTo(x) < 0)
+                            assert(!w.isConvertibleFrom(x));
+                        else
+                            assert(w.isConvertibleFrom(x));
+                    }
+                }
+            }
+            // check relations with floating types:
+            if (w.isFloating()) {
+                for (Wrapper x : values()) {
+                    if (w == x)  continue;
+                    if (x.isSigned())
+                        assert(w.isConvertibleFrom(x));
+                    else if (x.isFloating()) {
+                        if (w.compareTo(x) < 0)
+                            assert(!w.isConvertibleFrom(x));
+                        else
+                            assert(w.isConvertibleFrom(x));
+                    }
+                }
+            }
+        }
+        return true;  // i.e., assert(true)
+    }
+
     /** Produce a zero value for the given wrapper type.
      *  This will be a numeric zero for a number or character,
      *  false for a boolean, and null for a reference or void.
@@ -549,7 +623,7 @@
     }
 
     private static boolean boolValue(long bits) {
-        //bits &= 1;  // simple 31-bit zero extension
+        bits &= 1;  // simple 31-bit zero extension
         return (bits != 0);
     }
 
@@ -559,4 +633,31 @@
     private static RuntimeException newIllegalArgumentException(String message) {
         return new IllegalArgumentException(message);
     }
+
+    // primitive array support
+    public Object makeArray(int len) {
+        return java.lang.reflect.Array.newInstance(primitiveType, len);
+    }
+    public Class<?> arrayType() {
+        return emptyArray.getClass();
+    }
+    public void copyArrayUnboxing(Object[] values, int vpos, Object a, int apos, int length) {
+        if (a.getClass() != arrayType())
+            arrayType().cast(a);  // throw NPE or CCE if bad type
+        for (int i = 0; i < length; i++) {
+            Object value = values[i+vpos];
+            value = convert(value, primitiveType);
+            java.lang.reflect.Array.set(a, i+apos, value);
+        }
+    }
+    public void copyArrayBoxing(Object a, int apos, Object[] values, int vpos, int length) {
+        if (a.getClass() != arrayType())
+            arrayType().cast(a);  // throw NPE or CCE if bad type
+        for (int i = 0; i < length; i++) {
+            Object value = java.lang.reflect.Array.get(a, i+apos);
+            //Already done: value = convert(value, primitiveType);
+            assert(value.getClass() == wrapperType);
+            values[i+vpos] = value;
+        }
+    }
 }
--- a/jdk/src/share/classes/sun/java2d/opengl/OGLRenderer.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/opengl/OGLRenderer.java	Wed May 18 13:19:32 2011 +0200
@@ -102,15 +102,20 @@
             final ParallelogramPipe realpipe = oglr.getAAParallelogramPipe();
             return new ParallelogramPipe() {
                 public void fillParallelogram(SunGraphics2D sg2d,
+                                              double ux1, double uy1,
+                                              double ux2, double uy2,
                                               double x, double y,
                                               double dx1, double dy1,
                                               double dx2, double dy2)
                 {
                     GraphicsPrimitive.tracePrimitive("OGLFillAAParallelogram");
                     realpipe.fillParallelogram(sg2d,
+                                               ux1, uy1, ux2, uy2,
                                                x, y, dx1, dy1, dx2, dy2);
                 }
                 public void drawParallelogram(SunGraphics2D sg2d,
+                                              double ux1, double uy1,
+                                              double ux2, double uy2,
                                               double x, double y,
                                               double dx1, double dy1,
                                               double dx2, double dy2,
@@ -118,6 +123,7 @@
                 {
                     GraphicsPrimitive.tracePrimitive("OGLDrawAAParallelogram");
                     realpipe.drawParallelogram(sg2d,
+                                               ux1, uy1, ux2, uy2,
                                                x, y, dx1, dy1, dx2, dy2,
                                                lw1, lw2);
                 }
@@ -166,21 +172,29 @@
             oglr.fillSpans(sg2d, si, transx, transy);
         }
         public void fillParallelogram(SunGraphics2D sg2d,
+                                      double ux1, double uy1,
+                                      double ux2, double uy2,
                                       double x, double y,
                                       double dx1, double dy1,
                                       double dx2, double dy2)
         {
             GraphicsPrimitive.tracePrimitive("OGLFillParallelogram");
-            oglr.fillParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2);
+            oglr.fillParallelogram(sg2d,
+                                   ux1, uy1, ux2, uy2,
+                                   x, y, dx1, dy1, dx2, dy2);
         }
         public void drawParallelogram(SunGraphics2D sg2d,
+                                      double ux1, double uy1,
+                                      double ux2, double uy2,
                                       double x, double y,
                                       double dx1, double dy1,
                                       double dx2, double dy2,
                                       double lw1, double lw2)
         {
             GraphicsPrimitive.tracePrimitive("OGLDrawParallelogram");
-            oglr.drawParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2, lw1, lw2);
+            oglr.drawParallelogram(sg2d,
+                                   ux1, uy1, ux2, uy2,
+                                   x, y, dx1, dy1, dx2, dy2, lw1, lw2);
         }
         public void copyArea(SunGraphics2D sg2d,
                              int x, int y, int w, int h, int dx, int dy)
--- a/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/pipe/AAShapePipe.java	Wed May 18 13:19:32 2011 +0200
@@ -68,21 +68,23 @@
         renderPath(sg, s, null);
     }
 
-    private static Rectangle2D computeBBox(double x, double y,
-                                           double dx1, double dy1,
-                                           double dx2, double dy2)
+    private static Rectangle2D computeBBox(double ux1, double uy1,
+                                           double ux2, double uy2)
     {
-        double lox, loy, hix, hiy;
-        lox = hix = x;
-        loy = hiy = y;
-        if (dx1 < 0) { lox += dx1; } else { hix += dx1; }
-        if (dy1 < 0) { loy += dy1; } else { hiy += dy1; }
-        if (dx2 < 0) { lox += dx2; } else { hix += dx2; }
-        if (dy2 < 0) { loy += dy2; } else { hiy += dy2; }
-        return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy);
+        if ((ux2 -= ux1) < 0) {
+            ux1 += ux2;
+            ux2 = -ux2;
+        }
+        if ((uy2 -= uy1) < 0) {
+            uy1 += uy2;
+            uy2 = -uy2;
+        }
+        return new Rectangle2D.Double(ux1, uy1, ux2, uy2);
     }
 
     public void fillParallelogram(SunGraphics2D sg,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2)
@@ -97,10 +99,12 @@
             return;
         }
 
-        renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
+        renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox);
     }
 
     public void drawParallelogram(SunGraphics2D sg,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2,
@@ -118,7 +122,7 @@
 
         // Note that bbox is of the original shape, not the wide path.
         // This is appropriate for handing to Paint methods...
-        renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox);
+        renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox);
     }
 
     private static byte[] theTile;
--- a/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java	Wed May 18 13:19:32 2011 +0200
@@ -66,6 +66,8 @@
     }
 
     public void fillParallelogram(SunGraphics2D sg,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2)
@@ -75,6 +77,8 @@
     }
 
     public void drawParallelogram(SunGraphics2D sg,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2,
--- a/jdk/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java	Wed May 18 13:19:32 2011 +0200
@@ -408,6 +408,8 @@
     }
 
     public void fillParallelogram(SunGraphics2D sg2d,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2)
@@ -429,6 +431,8 @@
     }
 
     public void drawParallelogram(SunGraphics2D sg2d,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2,
@@ -454,6 +458,8 @@
 
     private class AAParallelogramPipe implements ParallelogramPipe {
         public void fillParallelogram(SunGraphics2D sg2d,
+                                      double ux1, double uy1,
+                                      double ux2, double uy2,
                                       double x, double y,
                                       double dx1, double dy1,
                                       double dx2, double dy2)
@@ -475,6 +481,8 @@
         }
 
         public void drawParallelogram(SunGraphics2D sg2d,
+                                      double ux1, double uy1,
+                                      double ux2, double uy2,
                                       double x, double y,
                                       double dx1, double dy1,
                                       double dx2, double dy2,
--- a/jdk/src/share/classes/sun/java2d/pipe/LoopPipe.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/pipe/LoopPipe.java	Wed May 18 13:19:32 2011 +0200
@@ -352,6 +352,8 @@
     }
 
     public void fillParallelogram(SunGraphics2D sg2d,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2)
@@ -362,6 +364,8 @@
     }
 
     public void drawParallelogram(SunGraphics2D sg2d,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2,
--- a/jdk/src/share/classes/sun/java2d/pipe/ParallelogramPipe.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/pipe/ParallelogramPipe.java	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -40,9 +40,17 @@
  *          => (x+dx2, y+dy2)
  *          => origin
  * </pre>
+ * The four u[xy][12] parameters are the unsorted extreme coordinates
+ * of the primitive in user space.  They may have been generated by a
+ * line or a rectangle so they could have u[xy]2 < u[xy]1 in some cases.
+ * They should be sorted before calculating the bounds of the original
+ * primitive (such as for calculating the user space bounds for the
+ * Paint.createContext() method).
  */
 public interface ParallelogramPipe {
     public void fillParallelogram(SunGraphics2D sg,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2);
@@ -59,6 +67,8 @@
      * difference between the outer and inner parallelograms.
      */
     public void drawParallelogram(SunGraphics2D sg,
+                                  double ux1, double uy1,
+                                  double ux2, double uy2,
                                   double x, double y,
                                   double dx1, double dy1,
                                   double dx2, double dy2,
--- a/jdk/src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java	Wed May 18 13:19:32 2011 +0200
@@ -175,8 +175,8 @@
     }
 
     public boolean drawGeneralLine(SunGraphics2D sg2d,
-                                   double x1, double y1,
-                                   double x2, double y2)
+                                   double ux1, double uy1,
+                                   double ux2, double uy2)
     {
         if (sg2d.strokeState == SunGraphics2D.STROKE_CUSTOM ||
             sg2d.strokeState == SunGraphics2D.STROKE_THINDASHED)
@@ -194,13 +194,14 @@
         double lw = bs.getLineWidth();
         // Save the original dx, dy in case we need it to transform
         // the linewidth as a perpendicular vector below
-        double dx = x2 - x1;
-        double dy = y2 - y1;
+        double dx = ux2 - ux1;
+        double dy = uy2 - uy1;
+        double x1, y1, x2, y2;
         switch (sg2d.transformState) {
         case SunGraphics2D.TRANSFORM_GENERIC:
         case SunGraphics2D.TRANSFORM_TRANSLATESCALE:
             {
-                double coords[] = {x1, y1, x2, y2};
+                double coords[] = {ux1, uy1, ux2, uy2};
                 sg2d.transform.transform(coords, 0, coords, 0, 2);
                 x1 = coords[0];
                 y1 = coords[1];
@@ -213,13 +214,17 @@
             {
                 double tx = sg2d.transform.getTranslateX();
                 double ty = sg2d.transform.getTranslateY();
-                x1 += tx;
-                y1 += ty;
-                x2 += tx;
-                y2 += ty;
+                x1 = ux1 + tx;
+                y1 = uy1 + ty;
+                x2 = ux2 + tx;
+                y2 = uy2 + ty;
             }
             break;
         case SunGraphics2D.TRANSFORM_ISIDENT:
+            x1 = ux1;
+            y1 = uy1;
+            x2 = ux2;
+            y2 = uy2;
             break;
         default:
             throw new InternalError("unknown TRANSFORM state...");
@@ -279,7 +284,8 @@
             dx += udx;
             dy += udy;
         }
-        outrenderer.fillParallelogram(sg2d, px, py, -udy, udx, dx, dy);
+        outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2,
+                                      px, py, -udy, udx, dx, dy);
         return true;
     }
 
@@ -313,7 +319,8 @@
             px = newx;
             py = newy;
         }
-        outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2);
+        outrenderer.fillParallelogram(sg2d, rx, ry, rx+rw, ry+rh,
+                                      px, py, dx1, dy1, dx2, dy2);
     }
 
     public void drawRectangle(SunGraphics2D sg2d,
@@ -360,10 +367,12 @@
             // entire hole in the middle of the parallelogram
             // so we can just fill the outer parallelogram.
             fillOuterParallelogram(sg2d,
+                                   rx, ry, rx+rw, ry+rh,
                                    px, py, dx1, dy1, dx2, dy2,
                                    len1, len2, lw1, lw2);
         } else {
             outrenderer.drawParallelogram(sg2d,
+                                          rx, ry, rx+rw, ry+rh,
                                           px, py, dx1, dy1, dx2, dy2,
                                           lw1 / len1, lw2 / len2);
         }
@@ -377,6 +386,8 @@
      * and issues a single fillParallelogram request to fill it.
      */
     public void fillOuterParallelogram(SunGraphics2D sg2d,
+                                       double ux1, double uy1,
+                                       double ux2, double uy2,
                                        double px, double py,
                                        double dx1, double dy1,
                                        double dx2, double dy2,
@@ -412,6 +423,7 @@
         dx2 += udx2;
         dy2 += udy2;
 
-        outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2);
+        outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2,
+                                      px, py, dx1, dy1, dx2, dy2);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.management;
+
+import com.sun.management.GarbageCollectionNotificationInfo;
+import com.sun.management.GcInfo;
+import java.lang.reflect.Method;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+
+/**
+ * A CompositeData for GarbageCollectionNotificationInfo for the local management support.
+ * This class avoids the performance penalty paid to the
+ * construction of a CompositeData use in the local case.
+ */
+public class GarbageCollectionNotifInfoCompositeData extends LazyCompositeData {
+    private final GarbageCollectionNotificationInfo gcNotifInfo;
+
+    public GarbageCollectionNotifInfoCompositeData(GarbageCollectionNotificationInfo info) {
+        this.gcNotifInfo = info;
+    }
+
+    public GarbageCollectionNotificationInfo getGarbageCollectionNotifInfo() {
+        return gcNotifInfo;
+    }
+
+    public static CompositeData toCompositeData(GarbageCollectionNotificationInfo info) {
+        GarbageCollectionNotifInfoCompositeData gcnicd =
+            new GarbageCollectionNotifInfoCompositeData(info);
+        return gcnicd.getCompositeData();
+    }
+
+    private CompositeType getCompositeTypeByBuilder() {
+        final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() {
+                public GcInfoBuilder run() {
+                    try {
+                        Class cl = Class.forName("com.sun.management.GcInfo");
+                        Field f = cl.getDeclaredField("builder");
+                        f.setAccessible(true);
+                        return (GcInfoBuilder)f.get(gcNotifInfo.getGcInfo());
+                    } catch(ClassNotFoundException e) {
+                        return null;
+                    } catch(NoSuchFieldException e) {
+                        return null;
+                    } catch(IllegalAccessException e) {
+                        return null;
+                    }
+                }
+            });
+        CompositeType gict = null;
+        synchronized(compositeTypeByBuilder) {
+            gict = compositeTypeByBuilder.get(builder);
+            if(gict == null) {
+                OpenType[] gcNotifInfoItemTypes = new OpenType[] {
+                    SimpleType.STRING,
+                    SimpleType.STRING,
+                    SimpleType.STRING,
+                    builder.getGcInfoCompositeType(),
+                };
+                try {
+                    final String typeName =
+                        "sun.management.GarbageCollectionNotifInfoCompositeType";
+                    gict = new CompositeType(typeName,
+                                             "CompositeType for GC notification info",
+                                             gcNotifInfoItemNames,
+                                             gcNotifInfoItemNames,
+                                             gcNotifInfoItemTypes);
+                    compositeTypeByBuilder.put(builder,gict);
+                } catch (OpenDataException e) {
+                    // shouldn't reach here
+                    throw Util.newException(e);
+                }
+            }
+        }
+        return gict;
+    }
+
+    protected CompositeData getCompositeData() {
+        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
+        // gcNotifInfoItemNames!
+        final Object[] gcNotifInfoItemValues;
+        gcNotifInfoItemValues = new Object[] {
+            gcNotifInfo.getGcName(),
+            gcNotifInfo.getGcAction(),
+            gcNotifInfo.getGcCause(),
+            GcInfoCompositeData.toCompositeData(gcNotifInfo.getGcInfo())
+        };
+
+        CompositeType gict = getCompositeTypeByBuilder();
+
+        try {
+            return new CompositeDataSupport(gict,
+                                            gcNotifInfoItemNames,
+                                            gcNotifInfoItemValues);
+        } catch (OpenDataException e) {
+            // Should never reach here
+            throw new AssertionError(e);
+        }
+    }
+
+    //    private static MappedMXBeanType gcInfoMapType;
+    private static final String GC_NAME = "gcName";
+    private static final String GC_ACTION = "gcAction";
+    private static final String GC_CAUSE = "gcCause";
+    private static final String GC_INFO     = "gcInfo";
+    private static final String[] gcNotifInfoItemNames = {
+        GC_NAME,
+        GC_ACTION,
+        GC_CAUSE,
+        GC_INFO
+    };
+    private static HashMap<GcInfoBuilder,CompositeType> compositeTypeByBuilder =
+        new HashMap<GcInfoBuilder,CompositeType>();
+
+    public static String getGcName(CompositeData cd) {
+        String gcname = getString(cd, GC_NAME);
+        if (gcname == null) {
+            throw new IllegalArgumentException("Invalid composite data: " +
+                "Attribute " + GC_NAME + " has null value");
+        }
+        return gcname;
+    }
+
+    public static String getGcAction(CompositeData cd) {
+        String gcaction = getString(cd, GC_ACTION);
+        if (gcaction == null) {
+            throw new IllegalArgumentException("Invalid composite data: " +
+                "Attribute " + GC_ACTION + " has null value");
+        }
+        return gcaction;
+    }
+
+    public static String getGcCause(CompositeData cd) {
+        String gccause = getString(cd, GC_CAUSE);
+        if (gccause == null) {
+            throw new IllegalArgumentException("Invalid composite data: " +
+                "Attribute " + GC_CAUSE + " has null value");
+        }
+        return gccause;
+    }
+
+    public static GcInfo getGcInfo(CompositeData cd) {
+        CompositeData gcInfoData = (CompositeData) cd.get(GC_INFO);
+        return GcInfo.from(gcInfoData);
+    }
+
+    /** Validate if the input CompositeData has the expected
+     * CompositeType (i.e. contain all attributes with expected
+     * names and types).
+     */
+    public static void validateCompositeData(CompositeData cd) {
+        if (cd == null) {
+            throw new NullPointerException("Null CompositeData");
+        }
+
+        if (!isTypeMatched( getBaseGcNotifInfoCompositeType(), cd.getCompositeType())) {
+            throw new IllegalArgumentException(
+                "Unexpected composite type for GarbageCollectionNotificationInfo");
+        }
+    }
+
+    // This is only used for validation.
+    private static CompositeType baseGcNotifInfoCompositeType = null;
+    private static synchronized CompositeType getBaseGcNotifInfoCompositeType() {
+        if (baseGcNotifInfoCompositeType == null) {
+            try {
+                OpenType[] baseGcNotifInfoItemTypes = new OpenType[] {
+                    SimpleType.STRING,
+                    SimpleType.STRING,
+                    SimpleType.STRING,
+                    GcInfoCompositeData.getBaseGcInfoCompositeType()
+                };
+                baseGcNotifInfoCompositeType =
+                    new CompositeType("sun.management.BaseGarbageCollectionNotifInfoCompositeType",
+                                      "CompositeType for Base GarbageCollectionNotificationInfo",
+                                      gcNotifInfoItemNames,
+                                      gcNotifInfoItemNames,
+                                      baseGcNotifInfoItemTypes);
+            } catch (OpenDataException e) {
+                // shouldn't reach here
+                throw Util.newException(e);
+            }
+        }
+        return baseGcNotifInfoCompositeType;
+    }
+
+    private static final long serialVersionUID = -1805123446483771292L;
+}
--- a/jdk/src/share/classes/sun/management/GarbageCollectorImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/management/GarbageCollectorImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -26,6 +26,7 @@
 package sun.management;
 
 import com.sun.management.GarbageCollectorMXBean;
+import com.sun.management.GarbageCollectionNotificationInfo;
 import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryPoolMXBean;
 import java.lang.management.MemoryUsage;
@@ -35,9 +36,15 @@
 import javax.management.MBeanInfo;
 import javax.management.MBeanAttributeInfo;
 import javax.management.ObjectName;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ListenerNotFoundException;
 
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 
 /**
  * Implementation class for the garbage collector.
@@ -78,19 +85,111 @@
 
     // Sun JDK extension
     private GcInfoBuilder gcInfoBuilder;
+
+    private synchronized GcInfoBuilder getGcInfoBuilder() {
+        if(gcInfoBuilder == null) {
+            gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames());
+        }
+        return gcInfoBuilder;
+    }
+
     public GcInfo getLastGcInfo() {
+        GcInfo info = getGcInfoBuilder().getLastGcInfo();
+        return info;
+    }
+
+    private final static String notifName =
+        "javax.management.Notification";
+
+    private final static String[] gcNotifTypes = {
+        GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION
+    };
+
+    private MBeanNotificationInfo[] notifInfo = null;
+    public MBeanNotificationInfo[] getNotificationInfo() {
         synchronized (this) {
-            if (gcInfoBuilder == null) {
-                 gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames());
+            if (notifInfo == null) {
+                 notifInfo = new MBeanNotificationInfo[1];
+                 notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes,
+                                                          notifName,
+                                                          "GC Notification");
             }
         }
+        return notifInfo;
+    }
 
-        GcInfo info = gcInfoBuilder.getLastGcInfo();
-        return info;
+    private static long seqNumber = 0;
+    private static long getNextSeqNumber() {
+        return ++seqNumber;
+    }
+
+    void createGCNotification(long timestamp,
+                              String gcName,
+                              String gcAction,
+                              String gcCause,
+                              GcInfo gcInfo)  {
+
+        if (!hasListeners()) {
+            return;
+        }
+
+        Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION,
+                                              getObjectName(),
+                                              getNextSeqNumber(),
+                                              timestamp,
+                                              gcName);
+        GarbageCollectionNotificationInfo info =
+            new GarbageCollectionNotificationInfo(gcName,
+                                                  gcAction,
+                                                  gcCause,
+                                                  gcInfo);
+
+        CompositeData cd =
+            GarbageCollectionNotifInfoCompositeData.toCompositeData(info);
+        notif.setUserData(cd);
+        sendNotification(notif);
+    }
+
+    public synchronized void addNotificationListener(NotificationListener listener,
+                                                     NotificationFilter filter,
+                                                     Object handback)
+    {
+        boolean before = hasListeners();
+        super.addNotificationListener(listener, filter, handback);
+        boolean after = hasListeners();
+        if (!before && after) {
+            setNotificationEnabled(this, true);
+        }
+    }
+
+    public synchronized void removeNotificationListener(NotificationListener listener)
+        throws ListenerNotFoundException {
+        boolean before = hasListeners();
+        super.removeNotificationListener(listener);
+        boolean after = hasListeners();
+        if (before && !after) {
+            setNotificationEnabled(this,false);
+        }
+    }
+
+    public synchronized void removeNotificationListener(NotificationListener listener,
+                                                        NotificationFilter filter,
+                                                        Object handback)
+            throws ListenerNotFoundException
+    {
+        boolean before = hasListeners();
+        super.removeNotificationListener(listener,filter,handback);
+        boolean after = hasListeners();
+        if (before && !after) {
+            setNotificationEnabled(this,false);
+        }
     }
 
     public ObjectName getObjectName() {
         return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName());
     }
 
+    native void setNotificationEnabled(GarbageCollectorMXBean gc,
+                                       boolean enabled);
+
 }
--- a/jdk/src/share/classes/sun/management/GcInfoCompositeData.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/management/GcInfoCompositeData.java	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -27,6 +27,7 @@
 
 import java.lang.management.MemoryUsage;
 import java.lang.reflect.Method;
+import java.lang.reflect.Field;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.HashMap;
@@ -41,6 +42,9 @@
 import javax.management.openmbean.OpenType;
 import javax.management.openmbean.OpenDataException;
 import com.sun.management.GcInfo;
+import com.sun.management.GarbageCollectionNotificationInfo;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 /**
  * A CompositeData for GcInfo for the local management support.
@@ -64,6 +68,44 @@
         return info;
     }
 
+    public static CompositeData toCompositeData(final GcInfo info) {
+        final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() {
+                        public GcInfoBuilder run() {
+                            try {
+                                Class cl = Class.forName("com.sun.management.GcInfo");
+                                Field f = cl.getDeclaredField("builder");
+                                f.setAccessible(true);
+                                return (GcInfoBuilder)f.get(info);
+                            } catch(ClassNotFoundException e) {
+                                return null;
+                            } catch(NoSuchFieldException e) {
+                                return null;
+                            } catch(IllegalAccessException e) {
+                                return null;
+                            }
+                        }
+                    });
+        final Object[] extAttr = AccessController.doPrivileged (new PrivilegedAction<Object[]>() {
+                        public Object[] run() {
+                            try {
+                                Class cl = Class.forName("com.sun.management.GcInfo");
+                                Field f = cl.getDeclaredField("extAttributes");
+                                f.setAccessible(true);
+                                return (Object[])f.get(info);
+                            } catch(ClassNotFoundException e) {
+                                return null;
+                            } catch(NoSuchFieldException e) {
+                                return null;
+                            } catch(IllegalAccessException e) {
+                                return null;
+                            }
+                        }
+                    });
+        GcInfoCompositeData gcicd =
+            new GcInfoCompositeData(info,builder,extAttr);
+        return gcicd.getCompositeData();
+    }
+
     protected CompositeData getCompositeData() {
         // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
         // baseGcInfoItemNames!
@@ -115,7 +157,6 @@
         }
     }
 
-
     private static final String ID                     = "id";
     private static final String START_TIME             = "startTime";
     private static final String END_TIME               = "endTime";
@@ -231,7 +272,7 @@
 
     // This is only used for validation.
     private static CompositeType baseGcInfoCompositeType = null;
-    private static synchronized CompositeType getBaseGcInfoCompositeType() {
+    static synchronized CompositeType getBaseGcInfoCompositeType() {
         if (baseGcInfoCompositeType == null) {
             try {
                 baseGcInfoCompositeType =
--- a/jdk/src/share/classes/sun/management/MemoryManagerImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/management/MemoryManagerImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -29,6 +29,7 @@
 import java.lang.management.MemoryManagerMXBean;
 import java.lang.management.MemoryPoolMXBean;
 
+import javax.management.MBeanNotificationInfo;
 import javax.management.ObjectName;
 
 /**
@@ -38,7 +39,8 @@
  * ManagementFactory.getMemoryManagerMXBeans() returns a list
  * of instances of this class.
  */
-class MemoryManagerImpl implements MemoryManagerMXBean {
+class MemoryManagerImpl extends NotificationEmitterSupport
+    implements MemoryManagerMXBean {
 
     private final String  name;
     private final boolean isValid;
@@ -76,6 +78,16 @@
     }
     private native MemoryPoolMXBean[] getMemoryPools0();
 
+    private MBeanNotificationInfo[] notifInfo = null;
+    public MBeanNotificationInfo[] getNotificationInfo() {
+        synchronized (this) {
+            if(notifInfo == null) {
+                notifInfo = new MBeanNotificationInfo[0];
+            }
+        }
+        return notifInfo;
+    }
+
     public ObjectName getObjectName() {
         return Util.newObjectName(ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE, getName());
     }
--- a/jdk/src/share/classes/sun/management/VMManagement.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/management/VMManagement.java	Wed May 18 13:19:32 2011 +0200
@@ -45,6 +45,7 @@
     public boolean isSynchronizerUsageSupported();
     public boolean isThreadAllocatedMemorySupported();
     public boolean isThreadAllocatedMemoryEnabled();
+    public boolean isGcNotificationSupported();
 
     // Class Loading Subsystem
     public long    getTotalClassCount();
--- a/jdk/src/share/classes/sun/management/VMManagementImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/management/VMManagementImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -56,6 +56,8 @@
     private static boolean objectMonitorUsageSupport;
     private static boolean synchronizerUsageSupport;
     private static boolean threadAllocatedMemorySupport;
+    private static boolean gcNotificationSupport;
+
 
     static {
         version = getVersion0();
@@ -100,6 +102,10 @@
         return threadAllocatedMemorySupport;
     }
 
+    public boolean isGcNotificationSupported() {
+        return gcNotificationSupport;
+    }
+
     public native boolean isThreadContentionMonitoringEnabled();
     public native boolean isThreadCpuTimeEnabled();
     public native boolean isThreadAllocatedMemoryEnabled();
--- a/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -28,7 +28,7 @@
 import java.nio.channels.*;
 import java.net.SocketAddress;
 import java.net.SocketOption;
-import java.net.StandardSocketOption;
+import java.net.StandardSocketOptions;
 import java.net.InetSocketAddress;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -214,8 +214,8 @@
 
         private static Set<SocketOption<?>> defaultOptions() {
             HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2);
-            set.add(StandardSocketOption.SO_RCVBUF);
-            set.add(StandardSocketOption.SO_REUSEADDR);
+            set.add(StandardSocketOptions.SO_RCVBUF);
+            set.add(StandardSocketOptions.SO_REUSEADDR);
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -28,7 +28,7 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.*;
 import java.net.SocketOption;
-import java.net.StandardSocketOption;
+import java.net.StandardSocketOptions;
 import java.net.SocketAddress;
 import java.net.InetSocketAddress;
 import java.io.IOException;
@@ -483,11 +483,11 @@
 
         private static Set<SocketOption<?>> defaultOptions() {
             HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(5);
-            set.add(StandardSocketOption.SO_SNDBUF);
-            set.add(StandardSocketOption.SO_RCVBUF);
-            set.add(StandardSocketOption.SO_KEEPALIVE);
-            set.add(StandardSocketOption.SO_REUSEADDR);
-            set.add(StandardSocketOption.TCP_NODELAY);
+            set.add(StandardSocketOptions.SO_SNDBUF);
+            set.add(StandardSocketOptions.SO_RCVBUF);
+            set.add(StandardSocketOptions.SO_KEEPALIVE);
+            set.add(StandardSocketOptions.SO_REUSEADDR);
+            set.add(StandardSocketOptions.TCP_NODELAY);
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -188,7 +188,7 @@
         synchronized (stateLock) {
             ensureOpen();
 
-            if (name == StandardSocketOption.IP_TOS) {
+            if (name == StandardSocketOptions.IP_TOS) {
                 // IPv4 only; no-op for IPv6
                 if (family == StandardProtocolFamily.INET) {
                     Net.setSocketOption(fd, family, name, value);
@@ -196,15 +196,15 @@
                 return this;
             }
 
-            if (name == StandardSocketOption.IP_MULTICAST_TTL ||
-                name == StandardSocketOption.IP_MULTICAST_LOOP)
+            if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
+                name == StandardSocketOptions.IP_MULTICAST_LOOP)
             {
                 // options are protocol dependent
                 Net.setSocketOption(fd, family, name, value);
                 return this;
             }
 
-            if (name == StandardSocketOption.IP_MULTICAST_IF) {
+            if (name == StandardSocketOptions.IP_MULTICAST_IF) {
                 if (value == null)
                     throw new IllegalArgumentException("Cannot set IP_MULTICAST_IF to 'null'");
                 NetworkInterface interf = (NetworkInterface)value;
@@ -243,7 +243,7 @@
         synchronized (stateLock) {
             ensureOpen();
 
-            if (name == StandardSocketOption.IP_TOS) {
+            if (name == StandardSocketOptions.IP_TOS) {
                 // IPv4 only; always return 0 on IPv6
                 if (family == StandardProtocolFamily.INET) {
                     return (T) Net.getSocketOption(fd, family, name);
@@ -252,13 +252,13 @@
                 }
             }
 
-            if (name == StandardSocketOption.IP_MULTICAST_TTL ||
-                name == StandardSocketOption.IP_MULTICAST_LOOP)
+            if (name == StandardSocketOptions.IP_MULTICAST_TTL ||
+                name == StandardSocketOptions.IP_MULTICAST_LOOP)
             {
                 return (T) Net.getSocketOption(fd, family, name);
             }
 
-            if (name == StandardSocketOption.IP_MULTICAST_IF) {
+            if (name == StandardSocketOptions.IP_MULTICAST_IF) {
                 if (family == StandardProtocolFamily.INET) {
                     int address = Net.getInterface4(fd);
                     if (address == 0)
@@ -291,14 +291,14 @@
 
         private static Set<SocketOption<?>> defaultOptions() {
             HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(8);
-            set.add(StandardSocketOption.SO_SNDBUF);
-            set.add(StandardSocketOption.SO_RCVBUF);
-            set.add(StandardSocketOption.SO_REUSEADDR);
-            set.add(StandardSocketOption.SO_BROADCAST);
-            set.add(StandardSocketOption.IP_TOS);
-            set.add(StandardSocketOption.IP_MULTICAST_IF);
-            set.add(StandardSocketOption.IP_MULTICAST_TTL);
-            set.add(StandardSocketOption.IP_MULTICAST_LOOP);
+            set.add(StandardSocketOptions.SO_SNDBUF);
+            set.add(StandardSocketOptions.SO_RCVBUF);
+            set.add(StandardSocketOptions.SO_REUSEADDR);
+            set.add(StandardSocketOptions.SO_BROADCAST);
+            set.add(StandardSocketOptions.IP_TOS);
+            set.add(StandardSocketOptions.IP_MULTICAST_IF);
+            set.add(StandardSocketOptions.IP_MULTICAST_TTL);
+            set.add(StandardSocketOptions.IP_MULTICAST_LOOP);
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramSocketAdaptor.java	Wed May 18 13:19:32 2011 +0200
@@ -312,46 +312,46 @@
     public void setSendBufferSize(int size) throws SocketException {
         if (size <= 0)
             throw new IllegalArgumentException("Invalid send size");
-        setIntOption(StandardSocketOption.SO_SNDBUF, size);
+        setIntOption(StandardSocketOptions.SO_SNDBUF, size);
     }
 
     public int getSendBufferSize() throws SocketException {
-        return getIntOption(StandardSocketOption.SO_SNDBUF);
+        return getIntOption(StandardSocketOptions.SO_SNDBUF);
     }
 
     public void setReceiveBufferSize(int size) throws SocketException {
         if (size <= 0)
             throw new IllegalArgumentException("Invalid receive size");
-        setIntOption(StandardSocketOption.SO_RCVBUF, size);
+        setIntOption(StandardSocketOptions.SO_RCVBUF, size);
     }
 
     public int getReceiveBufferSize() throws SocketException {
-        return getIntOption(StandardSocketOption.SO_RCVBUF);
+        return getIntOption(StandardSocketOptions.SO_RCVBUF);
     }
 
     public void setReuseAddress(boolean on) throws SocketException {
-        setBooleanOption(StandardSocketOption.SO_REUSEADDR, on);
+        setBooleanOption(StandardSocketOptions.SO_REUSEADDR, on);
     }
 
     public boolean getReuseAddress() throws SocketException {
-        return getBooleanOption(StandardSocketOption.SO_REUSEADDR);
+        return getBooleanOption(StandardSocketOptions.SO_REUSEADDR);
 
     }
 
     public void setBroadcast(boolean on) throws SocketException {
-        setBooleanOption(StandardSocketOption.SO_BROADCAST, on);
+        setBooleanOption(StandardSocketOptions.SO_BROADCAST, on);
     }
 
     public boolean getBroadcast() throws SocketException {
-        return getBooleanOption(StandardSocketOption.SO_BROADCAST);
+        return getBooleanOption(StandardSocketOptions.SO_BROADCAST);
     }
 
     public void setTrafficClass(int tc) throws SocketException {
-        setIntOption(StandardSocketOption.IP_TOS, tc);
+        setIntOption(StandardSocketOptions.IP_TOS, tc);
     }
 
     public int getTrafficClass() throws SocketException {
-        return getIntOption(StandardSocketOption.IP_TOS);
+        return getIntOption(StandardSocketOptions.IP_TOS);
     }
 
     public void close() {
--- a/jdk/src/share/classes/sun/nio/ch/ExtendedSocketOption.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/ExtendedSocketOption.java	Wed May 18 13:19:32 2011 +0200
@@ -29,7 +29,7 @@
 
 /**
  * Defines socket options that are supported by the implementation
- * but not defined in StandardSocketOption.
+ * but not defined in StandardSocketOptions.
  */
 
 class ExtendedSocketOption {
--- a/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java	Wed May 18 13:19:32 2011 +0200
@@ -96,11 +96,16 @@
                     break;
             }
             waitingToEmpty = true;
+            boolean interrupted = false;
             while (used > 0) {
                 try {
                     wait();
-                } catch (InterruptedException ignore) { }
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                }
             }
+            if (interrupted)
+                Thread.currentThread().interrupt();
         }
     }
 }
--- a/jdk/src/share/classes/sun/nio/ch/Net.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Net.java	Wed May 18 13:19:32 2011 +0200
@@ -237,26 +237,26 @@
             throw new AssertionError("Should not reach here");
 
         // special handling
-        if (name == StandardSocketOption.SO_RCVBUF ||
-            name == StandardSocketOption.SO_SNDBUF)
+        if (name == StandardSocketOptions.SO_RCVBUF ||
+            name == StandardSocketOptions.SO_SNDBUF)
         {
             int i = ((Integer)value).intValue();
             if (i < 0)
                 throw new IllegalArgumentException("Invalid send/receive buffer size");
         }
-        if (name == StandardSocketOption.SO_LINGER) {
+        if (name == StandardSocketOptions.SO_LINGER) {
             int i = ((Integer)value).intValue();
             if (i < 0)
                 value = Integer.valueOf(-1);
             if (i > 65535)
                 value = Integer.valueOf(65535);
         }
-        if (name == StandardSocketOption.IP_TOS) {
+        if (name == StandardSocketOptions.IP_TOS) {
             int i = ((Integer)value).intValue();
             if (i < 0 || i > 255)
                 throw new IllegalArgumentException("Invalid IP_TOS value");
         }
-        if (name == StandardSocketOption.IP_MULTICAST_TTL) {
+        if (name == StandardSocketOptions.IP_MULTICAST_TTL) {
             int i = ((Integer)value).intValue();
             if (i < 0 || i > 255)
                 throw new IllegalArgumentException("Invalid TTL/hop value");
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java	Wed May 18 13:19:32 2011 +0200
@@ -169,7 +169,7 @@
 
     public void setReuseAddress(boolean on) throws SocketException {
         try {
-            ssc.setOption(StandardSocketOption.SO_REUSEADDR, on);
+            ssc.setOption(StandardSocketOptions.SO_REUSEADDR, on);
         } catch (IOException x) {
             Net.translateToSocketException(x);
         }
@@ -177,7 +177,7 @@
 
     public boolean getReuseAddress() throws SocketException {
         try {
-            return ssc.getOption(StandardSocketOption.SO_REUSEADDR).booleanValue();
+            return ssc.getOption(StandardSocketOptions.SO_REUSEADDR).booleanValue();
         } catch (IOException x) {
             Net.translateToSocketException(x);
             return false;       // Never happens
@@ -197,7 +197,7 @@
         if (size <= 0)
             throw new IllegalArgumentException("size cannot be 0 or negative");
         try {
-            ssc.setOption(StandardSocketOption.SO_RCVBUF, size);
+            ssc.setOption(StandardSocketOptions.SO_RCVBUF, size);
         } catch (IOException x) {
             Net.translateToSocketException(x);
         }
@@ -205,7 +205,7 @@
 
     public int getReceiveBufferSize() throws SocketException {
         try {
-            return ssc.getOption(StandardSocketOption.SO_RCVBUF).intValue();
+            return ssc.getOption(StandardSocketOptions.SO_RCVBUF).intValue();
         } catch (IOException x) {
             Net.translateToSocketException(x);
             return -1;          // Never happens
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -160,8 +160,8 @@
 
         private static Set<SocketOption<?>> defaultOptions() {
             HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(2);
-            set.add(StandardSocketOption.SO_RCVBUF);
-            set.add(StandardSocketOption.SO_REUSEADDR);
+            set.add(StandardSocketOptions.SO_RCVBUF);
+            set.add(StandardSocketOptions.SO_REUSEADDR);
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java	Wed May 18 13:19:32 2011 +0200
@@ -318,21 +318,21 @@
     }
 
     public void setTcpNoDelay(boolean on) throws SocketException {
-        setBooleanOption(StandardSocketOption.TCP_NODELAY, on);
+        setBooleanOption(StandardSocketOptions.TCP_NODELAY, on);
     }
 
     public boolean getTcpNoDelay() throws SocketException {
-        return getBooleanOption(StandardSocketOption.TCP_NODELAY);
+        return getBooleanOption(StandardSocketOptions.TCP_NODELAY);
     }
 
     public void setSoLinger(boolean on, int linger) throws SocketException {
         if (!on)
             linger = -1;
-        setIntOption(StandardSocketOption.SO_LINGER, linger);
+        setIntOption(StandardSocketOptions.SO_LINGER, linger);
     }
 
     public int getSoLinger() throws SocketException {
-        return getIntOption(StandardSocketOption.SO_LINGER);
+        return getIntOption(StandardSocketOptions.SO_LINGER);
     }
 
     public void sendUrgentData(int data) throws IOException {
@@ -366,46 +366,46 @@
         // size 0 valid for SocketChannel, invalid for Socket
         if (size <= 0)
             throw new IllegalArgumentException("Invalid send size");
-        setIntOption(StandardSocketOption.SO_SNDBUF, size);
+        setIntOption(StandardSocketOptions.SO_SNDBUF, size);
     }
 
     public int getSendBufferSize() throws SocketException {
-        return getIntOption(StandardSocketOption.SO_SNDBUF);
+        return getIntOption(StandardSocketOptions.SO_SNDBUF);
     }
 
     public void setReceiveBufferSize(int size) throws SocketException {
         // size 0 valid for SocketChannel, invalid for Socket
         if (size <= 0)
             throw new IllegalArgumentException("Invalid receive size");
-        setIntOption(StandardSocketOption.SO_RCVBUF, size);
+        setIntOption(StandardSocketOptions.SO_RCVBUF, size);
     }
 
     public int getReceiveBufferSize() throws SocketException {
-        return getIntOption(StandardSocketOption.SO_RCVBUF);
+        return getIntOption(StandardSocketOptions.SO_RCVBUF);
     }
 
     public void setKeepAlive(boolean on) throws SocketException {
-        setBooleanOption(StandardSocketOption.SO_KEEPALIVE, on);
+        setBooleanOption(StandardSocketOptions.SO_KEEPALIVE, on);
     }
 
     public boolean getKeepAlive() throws SocketException {
-        return getBooleanOption(StandardSocketOption.SO_KEEPALIVE);
+        return getBooleanOption(StandardSocketOptions.SO_KEEPALIVE);
     }
 
     public void setTrafficClass(int tc) throws SocketException {
-        setIntOption(StandardSocketOption.IP_TOS, tc);
+        setIntOption(StandardSocketOptions.IP_TOS, tc);
     }
 
     public int getTrafficClass() throws SocketException {
-        return getIntOption(StandardSocketOption.IP_TOS);
+        return getIntOption(StandardSocketOptions.IP_TOS);
     }
 
     public void setReuseAddress(boolean on) throws SocketException {
-        setBooleanOption(StandardSocketOption.SO_REUSEADDR, on);
+        setBooleanOption(StandardSocketOptions.SO_REUSEADDR, on);
     }
 
     public boolean getReuseAddress() throws SocketException {
-        return getBooleanOption(StandardSocketOption.SO_REUSEADDR);
+        return getBooleanOption(StandardSocketOptions.SO_REUSEADDR);
     }
 
     public void close() throws IOException {
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -170,7 +170,7 @@
                 throw new ClosedChannelException();
 
             // special handling for IP_TOS: no-op when IPv6
-            if (name == StandardSocketOption.IP_TOS) {
+            if (name == StandardSocketOptions.IP_TOS) {
                 if (!Net.isIPv6Available())
                     Net.setSocketOption(fd, StandardProtocolFamily.INET, name, value);
                 return this;
@@ -197,7 +197,7 @@
                 throw new ClosedChannelException();
 
             // special handling for IP_TOS: always return 0 when IPv6
-            if (name == StandardSocketOption.IP_TOS) {
+            if (name == StandardSocketOptions.IP_TOS) {
                 return (Net.isIPv6Available()) ? (T) Integer.valueOf(0) :
                     (T) Net.getSocketOption(fd, StandardProtocolFamily.INET, name);
             }
@@ -212,14 +212,14 @@
 
         private static Set<SocketOption<?>> defaultOptions() {
             HashSet<SocketOption<?>> set = new HashSet<SocketOption<?>>(8);
-            set.add(StandardSocketOption.SO_SNDBUF);
-            set.add(StandardSocketOption.SO_RCVBUF);
-            set.add(StandardSocketOption.SO_KEEPALIVE);
-            set.add(StandardSocketOption.SO_REUSEADDR);
-            set.add(StandardSocketOption.SO_LINGER);
-            set.add(StandardSocketOption.TCP_NODELAY);
+            set.add(StandardSocketOptions.SO_SNDBUF);
+            set.add(StandardSocketOptions.SO_RCVBUF);
+            set.add(StandardSocketOptions.SO_KEEPALIVE);
+            set.add(StandardSocketOptions.SO_REUSEADDR);
+            set.add(StandardSocketOptions.SO_LINGER);
+            set.add(StandardSocketOptions.TCP_NODELAY);
             // additional options required by socket adaptor
-            set.add(StandardSocketOption.IP_TOS);
+            set.add(StandardSocketOptions.IP_TOS);
             set.add(ExtendedSocketOption.SO_OOBINLINE);
             return Collections.unmodifiableSet(set);
         }
--- a/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractPoller.java	Wed May 18 13:19:32 2011 +0200
@@ -105,16 +105,16 @@
         Set<WatchEvent.Kind<?>> eventSet = new HashSet<>(events.length);
         for (WatchEvent.Kind<?> event: events) {
             // standard events
-            if (event == StandardWatchEventKind.ENTRY_CREATE ||
-                event == StandardWatchEventKind.ENTRY_MODIFY ||
-                event == StandardWatchEventKind.ENTRY_DELETE)
+            if (event == StandardWatchEventKinds.ENTRY_CREATE ||
+                event == StandardWatchEventKinds.ENTRY_MODIFY ||
+                event == StandardWatchEventKinds.ENTRY_DELETE)
             {
                 eventSet.add(event);
                 continue;
             }
 
             // OVERFLOW is ignored
-            if (event == StandardWatchEventKind.OVERFLOW) {
+            if (event == StandardWatchEventKinds.OVERFLOW) {
                 if (events.length == 1)
                     throw new IllegalArgumentException("No events to register");
                 continue;
--- a/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/fs/AbstractWatchKey.java	Wed May 18 13:19:32 2011 +0200
@@ -42,8 +42,8 @@
     /**
      * Special event to signal overflow
      */
-    static final Event<Void> OVERFLOW_EVENT =
-        new Event<Void>(StandardWatchEventKind.OVERFLOW, null);
+    static final Event<Object> OVERFLOW_EVENT =
+        new Event<Object>(StandardWatchEventKinds.OVERFLOW, null);
 
     /**
      * Possible key states
@@ -103,14 +103,14 @@
      */
     @SuppressWarnings("unchecked")
     final void signalEvent(WatchEvent.Kind<?> kind, Object context) {
-        boolean isModify = (kind == StandardWatchEventKind.ENTRY_MODIFY);
+        boolean isModify = (kind == StandardWatchEventKinds.ENTRY_MODIFY);
         synchronized (this) {
             int size = events.size();
             if (size > 0) {
                 // if the previous event is an OVERFLOW event or this is a
                 // repeated event then we simply increment the counter
                 WatchEvent<?> prev = events.get(size-1);
-                if ((prev.kind() == StandardWatchEventKind.OVERFLOW) ||
+                if ((prev.kind() == StandardWatchEventKinds.OVERFLOW) ||
                     ((kind == prev.kind() &&
                      Objects.equals(context, prev.context()))))
                 {
@@ -124,7 +124,7 @@
                     if (isModify) {
                         WatchEvent<?> ev = lastModifyEvents.get(context);
                         if (ev != null) {
-                            assert ev.kind() == StandardWatchEventKind.ENTRY_MODIFY;
+                            assert ev.kind() == StandardWatchEventKinds.ENTRY_MODIFY;
                             ((Event<?>)ev).increment();
                             return;
                         }
@@ -138,7 +138,7 @@
                 // if the list has reached the limit then drop pending events
                 // and queue an OVERFLOW event
                 if (size >= MAX_EVENT_LIST_SIZE) {
-                    kind = StandardWatchEventKind.OVERFLOW;
+                    kind = StandardWatchEventKinds.OVERFLOW;
                     isModify = false;
                     context = null;
                 }
@@ -149,7 +149,7 @@
                 new Event<Object>((WatchEvent.Kind<Object>)kind, context);
             if (isModify) {
                 lastModifyEvents.put(context, ev);
-            } else if (kind == StandardWatchEventKind.OVERFLOW) {
+            } else if (kind == StandardWatchEventKinds.OVERFLOW) {
                 // drop all pending events
                 events.clear();
                 lastModifyEvents.clear();
--- a/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/nio/fs/PollingWatchService.java	Wed May 18 13:19:32 2011 +0200
@@ -80,16 +80,16 @@
             new HashSet<WatchEvent.Kind<?>>(events.length);
         for (WatchEvent.Kind<?> event: events) {
             // standard events
-            if (event == StandardWatchEventKind.ENTRY_CREATE ||
-                event == StandardWatchEventKind.ENTRY_MODIFY ||
-                event == StandardWatchEventKind.ENTRY_DELETE)
+            if (event == StandardWatchEventKinds.ENTRY_CREATE ||
+                event == StandardWatchEventKinds.ENTRY_MODIFY ||
+                event == StandardWatchEventKinds.ENTRY_DELETE)
             {
                 eventSet.add(event);
                 continue;
             }
 
             // OVERFLOW is ignored
-            if (event == StandardWatchEventKind.OVERFLOW) {
+            if (event == StandardWatchEventKinds.OVERFLOW) {
                 if (events.length == 1)
                     throw new IllegalArgumentException("No events to register");
                 continue;
@@ -355,16 +355,16 @@
                                      new CacheEntry(lastModified, tickCount));
 
                         // queue ENTRY_CREATE if event enabled
-                        if (events.contains(StandardWatchEventKind.ENTRY_CREATE)) {
-                            signalEvent(StandardWatchEventKind.ENTRY_CREATE, entry.getFileName());
+                        if (events.contains(StandardWatchEventKinds.ENTRY_CREATE)) {
+                            signalEvent(StandardWatchEventKinds.ENTRY_CREATE, entry.getFileName());
                             continue;
                         } else {
                             // if ENTRY_CREATE is not enabled and ENTRY_MODIFY is
                             // enabled then queue event to avoid missing out on
                             // modifications to the file immediately after it is
                             // created.
-                            if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
-                                signalEvent(StandardWatchEventKind.ENTRY_MODIFY, entry.getFileName());
+                            if (events.contains(StandardWatchEventKinds.ENTRY_MODIFY)) {
+                                signalEvent(StandardWatchEventKinds.ENTRY_MODIFY, entry.getFileName());
                             }
                         }
                         continue;
@@ -372,8 +372,8 @@
 
                     // check if file has changed
                     if (e.lastModified != lastModified) {
-                        if (events.contains(StandardWatchEventKind.ENTRY_MODIFY)) {
-                            signalEvent(StandardWatchEventKind.ENTRY_MODIFY,
+                        if (events.contains(StandardWatchEventKinds.ENTRY_MODIFY)) {
+                            signalEvent(StandardWatchEventKinds.ENTRY_MODIFY,
                                         entry.getFileName());
                         }
                     }
@@ -403,8 +403,8 @@
                     Path name = mapEntry.getKey();
                     // remove from map and queue delete event (if enabled)
                     i.remove();
-                    if (events.contains(StandardWatchEventKind.ENTRY_DELETE)) {
-                        signalEvent(StandardWatchEventKind.ENTRY_DELETE, name);
+                    if (events.contains(StandardWatchEventKinds.ENTRY_DELETE)) {
+                        signalEvent(StandardWatchEventKinds.ENTRY_DELETE, name);
                     }
                 }
             }
--- a/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/spi/GSSContextSpi.java	Wed May 18 13:19:32 2011 +0200
@@ -24,22 +24,10 @@
  */
 
 /*
- * ===========================================================================
- *  IBM Confidential
- *  OCO Source Materials
- *  Licensed Materials - Property of IBM
  *
  *  (C) Copyright IBM Corp. 1999 All Rights Reserved.
- *
- *  The source code for this program is not published or otherwise divested of
- *  its trade secrets, irrespective of what has been deposited with the U.S.
- *  Copyright Office.
- *
  *  Copyright 1997 The Open Group Research Institute.  All rights reserved.
- * ===========================================================================
- *
  */
-
 package sun.security.jgss.spi;
 
 import org.ietf.jgss.*;
--- a/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/JsseJce.java	Wed May 18 13:19:32 2011 +0200
@@ -62,7 +62,7 @@
     // Flag indicating whether EC crypto is available.
     // If null, then we have not checked yet.
     // If yes, then all the EC based crypto we need is available.
-    private static volatile Boolean ecAvailable;
+    private static Boolean ecAvailable;
 
     // Flag indicating whether Kerberos crypto is available.
     // If true, then all the Kerberos-based crypto we need is available.
@@ -190,7 +190,7 @@
         // no instantiation of this class
     }
 
-    static boolean isEcAvailable() {
+    synchronized static boolean isEcAvailable() {
         if (ecAvailable == null) {
             try {
                 JsseJce.getSignature(SIGNATURE_ECDSA);
@@ -206,7 +206,7 @@
         return ecAvailable;
     }
 
-    static void clearEcAvailable() {
+    synchronized static void clearEcAvailable() {
         ecAvailable = null;
     }
 
--- a/jdk/src/share/classes/sun/text/bidi/BidiBase.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/text/bidi/BidiBase.java	Wed May 18 13:19:32 2011 +0200
@@ -2889,10 +2889,6 @@
         verifyValidPara();
         verifyRange(start, 0, limit);
         verifyRange(limit, 0, length+1);
-        if (getParagraphIndex(start) != getParagraphIndex(limit - 1)) {
-            /* the line crosses a paragraph boundary */
-            throw new IllegalArgumentException();
-        }
 
         return BidiLine.setLine(bidi, this, newBidi, newBidiBase, start, limit);
     }
--- a/jdk/src/share/classes/sun/text/resources/BreakIteratorRules_th.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/classes/sun/text/resources/BreakIteratorRules_th.java	Wed May 18 13:19:32 2011 +0200
@@ -27,17 +27,7 @@
  */
 
 /*
- * IBM Confidential
- * OCO Source Materials
- *
- * IBM Java(tm)2 SDK, Standard Edition, v 1.2
- *
- * (C) Copyright IBM Corp. 1999
- *
- * The source code for this program is not published or otherwise divested of
- * its trade secrets, irrespective of what has been deposited with the U.S.
- * Copyright office.
- *
+ *  (C) Copyright IBM Corp. 1999 All Rights Reserved.
  */
 
 /*
--- a/jdk/src/share/javavm/export/jmm.h	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/javavm/export/jmm.h	Wed May 18 13:19:32 2011 +0200
@@ -48,7 +48,7 @@
   JMM_VERSION_1_0 = 0x20010000,
   JMM_VERSION_1_1 = 0x20010100, // JDK 6
   JMM_VERSION_1_2 = 0x20010200, // JDK 7
-  JMM_VERSION     = 0x20010200
+  JMM_VERSION     = 0x20010201
 };
 
 typedef struct {
@@ -293,6 +293,9 @@
                                                   jlongArray ids,
                                                   jboolean lockedMonitors,
                                                   jboolean lockedSynchronizers);
+   void         (JNICALL *SetGCNotificationEnabled) (JNIEnv *env,
+                                                  jobject mgr,
+                                                  jboolean enabled);
 } JmmInterface;
 
 #ifdef __cplusplus
--- a/jdk/src/share/native/sun/management/GarbageCollectorImpl.c	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/native/sun/management/GarbageCollectorImpl.c	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -36,3 +36,17 @@
   (JNIEnv *env, jobject mgr) {
     return jmm_interface->GetLongAttribute(env, mgr, JMM_GC_TIME_MS);
 }
+
+
+JNIEXPORT void JNICALL Java_sun_management_GarbageCollectorImpl_setNotificationEnabled
+(JNIEnv *env, jobject dummy, jobject gc,jboolean enabled) {
+
+    if (gc == NULL) {
+        JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
+        return;
+    }
+    if((jmm_version > JMM_VERSION_1_2)
+       || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=1))) {
+      jmm_interface->SetGCNotificationEnabled(env, gc, enabled);
+    }
+}
--- a/jdk/src/share/native/sun/management/VMManagementImpl.c	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/native/sun/management/VMManagementImpl.c	Wed May 18 13:19:32 2011 +0200
@@ -95,6 +95,13 @@
 
     value = mos.isThreadAllocatedMemorySupported;
     setStaticBooleanField(env, cls, "threadAllocatedMemorySupport", value);
+
+    if ((jmm_version > JMM_VERSION_1_2) ||
+        (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF) >= 1))) {
+        setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_TRUE);
+    } else {
+        setStaticBooleanField(env, cls, "gcNotificationSupport", JNI_FALSE);
+    }
 }
 
 JNIEXPORT jobjectArray JNICALL
--- a/jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/native/sun/nio/ch/genSocketOptionRegistry.c	Wed May 18 13:19:32 2011 +0200
@@ -63,7 +63,7 @@
     out("// AUTOMATICALLY GENERATED FILE - DO NOT EDIT                                  ");
     out("package sun.nio.ch;                                                            ");
     out("import java.net.SocketOption;                                                  ");
-    out("import java.net.StandardSocketOption;                                          ");
+    out("import java.net.StandardSocketOptions;                                         ");
     out("import java.net.ProtocolFamily;                                                ");
     out("import java.net.StandardProtocolFamily;                                        ");
     out("import java.util.Map;                                                          ");
@@ -73,7 +73,7 @@
     out("    private static class RegistryKey {                                         ");
     out("        private final SocketOption<?> name;                                    ");
     out("        private final ProtocolFamily family;                                   ");
-    out("        RegistryKey(SocketOption<?> name, ProtocolFamily family) {                ");
+    out("        RegistryKey(SocketOption<?> name, ProtocolFamily family) {             ");
     out("            this.name = name;                                                  ");
     out("            this.family = family;                                              ");
     out("        }                                                                      ");
@@ -95,23 +95,23 @@
     out("            Map<RegistryKey,OptionKey> map =                                   ");
     out("                new HashMap<RegistryKey,OptionKey>();                          ");
 
-    emit_unspec("StandardSocketOption.SO_BROADCAST", SOL_SOCKET, SO_BROADCAST);
-    emit_unspec("StandardSocketOption.SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE);
-    emit_unspec("StandardSocketOption.SO_LINGER",    SOL_SOCKET, SO_LINGER);
-    emit_unspec("StandardSocketOption.SO_SNDBUF",    SOL_SOCKET, SO_SNDBUF);
-    emit_unspec("StandardSocketOption.SO_RCVBUF",    SOL_SOCKET, SO_RCVBUF);
-    emit_unspec("StandardSocketOption.SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR);
-    emit_unspec("StandardSocketOption.TCP_NODELAY",  IPPROTO_TCP, TCP_NODELAY);
+    emit_unspec("StandardSocketOptions.SO_BROADCAST", SOL_SOCKET, SO_BROADCAST);
+    emit_unspec("StandardSocketOptions.SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE);
+    emit_unspec("StandardSocketOptions.SO_LINGER",    SOL_SOCKET, SO_LINGER);
+    emit_unspec("StandardSocketOptions.SO_SNDBUF",    SOL_SOCKET, SO_SNDBUF);
+    emit_unspec("StandardSocketOptions.SO_RCVBUF",    SOL_SOCKET, SO_RCVBUF);
+    emit_unspec("StandardSocketOptions.SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR);
+    emit_unspec("StandardSocketOptions.TCP_NODELAY",  IPPROTO_TCP, TCP_NODELAY);
 
-    emit_inet("StandardSocketOption.IP_TOS",            IPPROTO_IP,     IP_TOS);
-    emit_inet("StandardSocketOption.IP_MULTICAST_IF",   IPPROTO_IP,     IP_MULTICAST_IF);
-    emit_inet("StandardSocketOption.IP_MULTICAST_TTL",  IPPROTO_IP,     IP_MULTICAST_TTL);
-    emit_inet("StandardSocketOption.IP_MULTICAST_LOOP", IPPROTO_IP,     IP_MULTICAST_LOOP);
+    emit_inet("StandardSocketOptions.IP_TOS",            IPPROTO_IP,     IP_TOS);
+    emit_inet("StandardSocketOptions.IP_MULTICAST_IF",   IPPROTO_IP,     IP_MULTICAST_IF);
+    emit_inet("StandardSocketOptions.IP_MULTICAST_TTL",  IPPROTO_IP,     IP_MULTICAST_TTL);
+    emit_inet("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IP,     IP_MULTICAST_LOOP);
 
 #ifdef AF_INET6
-    emit_inet6("StandardSocketOption.IP_MULTICAST_IF",   IPPROTO_IPV6,  IPV6_MULTICAST_IF);
-    emit_inet6("StandardSocketOption.IP_MULTICAST_TTL",  IPPROTO_IPV6,  IPV6_MULTICAST_HOPS);
-    emit_inet6("StandardSocketOption.IP_MULTICAST_LOOP", IPPROTO_IPV6,  IPV6_MULTICAST_LOOP);
+    emit_inet6("StandardSocketOptions.IP_MULTICAST_IF",   IPPROTO_IPV6,  IPV6_MULTICAST_IF);
+    emit_inet6("StandardSocketOptions.IP_MULTICAST_TTL",  IPPROTO_IPV6,  IPV6_MULTICAST_HOPS);
+    emit_inet6("StandardSocketOptions.IP_MULTICAST_LOOP", IPPROTO_IPV6,  IPV6_MULTICAST_LOOP);
 #endif
 
     emit_unspec("ExtendedSocketOption.SO_OOBINLINE", SOL_SOCKET, SO_OOBINLINE);
--- a/jdk/src/share/sample/nio/chatserver/ChatServer.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/sample/nio/chatserver/ChatServer.java	Wed May 18 13:19:32 2011 +0200
@@ -32,7 +32,7 @@
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.net.StandardSocketOption;
+import java.net.StandardSocketOptions;
 import java.nio.channels.*;
 import java.util.*;
 import java.util.concurrent.Executors;
@@ -105,7 +105,7 @@
     */
     private AsynchronousServerSocketChannel createListener(AsynchronousChannelGroup channelGroup) throws IOException {
         final AsynchronousServerSocketChannel listener = openChannel(channelGroup);
-        listener.setOption(StandardSocketOption.SO_REUSEADDR, true);
+        listener.setOption(StandardSocketOptions.SO_REUSEADDR, true);
         listener.bind(new InetSocketAddress(port));
         return listener;
     }
@@ -123,7 +123,7 @@
     private void handleNewConnection(AsynchronousSocketChannel channel) {
         Client client = new Client(channel, new ClientReader(this, new NameReader(this)));
         try {
-            channel.setOption(StandardSocketOption.TCP_NODELAY, true);
+            channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
         } catch (IOException e) {
             // ignore
         }
--- a/jdk/src/share/sample/nio/file/WatchDir.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/sample/nio/file/WatchDir.java	Wed May 18 13:19:32 2011 +0200
@@ -30,7 +30,7 @@
  */
 
 import java.nio.file.*;
-import static java.nio.file.StandardWatchEventKind.*;
+import static java.nio.file.StandardWatchEventKinds.*;
 import static java.nio.file.LinkOption.*;
 import java.nio.file.attribute.*;
 import java.io.IOException;
--- a/jdk/src/share/sample/nio/multicast/Reader.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/sample/nio/multicast/Reader.java	Wed May 18 13:19:32 2011 +0200
@@ -96,7 +96,7 @@
             family = StandardProtocolFamily.INET6;
         }
         DatagramChannel dc = DatagramChannel.open(family)
-            .setOption(StandardSocketOption.SO_REUSEADDR, true)
+            .setOption(StandardSocketOptions.SO_REUSEADDR, true)
             .bind(new InetSocketAddress(target.port()));
 
         if (includeList.isEmpty()) {
--- a/jdk/src/share/sample/nio/multicast/Sender.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/share/sample/nio/multicast/Sender.java	Wed May 18 13:19:32 2011 +0200
@@ -59,7 +59,7 @@
             family = StandardProtocolFamily.INET6;
         DatagramChannel dc = DatagramChannel.open(family).bind(new InetSocketAddress(0));
         if (target.interf() != null) {
-            dc.setOption(StandardSocketOption.IP_MULTICAST_IF, target.interf());
+            dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, target.interf());
         }
 
         // send multicast packet
--- a/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XRobotPeer.java	Wed May 18 13:19:32 2011 +0200
@@ -48,7 +48,7 @@
     }
 
     public void dispose() {
-        _dispose();
+        // does nothing
     }
 
     public void mouseMove(int x, int y) {
@@ -88,7 +88,6 @@
     }
 
     private static native synchronized void setup(int numberOfButtons, int[] buttonDownMasks);
-    private static native synchronized void _dispose();
 
     private static native synchronized void mouseMoveImpl(X11GraphicsConfig xgc, int x, int y);
     private static native synchronized void mousePressImpl(int buttons);
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -55,7 +55,7 @@
 import com.sun.nio.sctp.SctpSocketOption;
 import sun.nio.ch.PollArrayWrapper;
 import sun.nio.ch.SelChImpl;
-import static com.sun.nio.sctp.SctpStandardSocketOption.*;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
 import static sun.nio.ch.SctpResultContainer.SEND_FAILED;
 import static sun.nio.ch.SctpResultContainer.ASSOCIATION_CHANGED;
 import static sun.nio.ch.SctpResultContainer.PEER_ADDRESS_CHANGED;
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpMultiChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -53,7 +53,7 @@
 import com.sun.nio.sctp.SctpChannel;
 import com.sun.nio.sctp.SctpMultiChannel;
 import com.sun.nio.sctp.SctpSocketOption;
-import static com.sun.nio.sctp.SctpStandardSocketOption.*;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
 import static sun.nio.ch.SctpResultContainer.*;
 
 /**
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpNet.java	Wed May 18 13:19:32 2011 +0200
@@ -35,7 +35,7 @@
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
 import com.sun.nio.sctp.SctpSocketOption;
-import static com.sun.nio.sctp.SctpStandardSocketOption.*;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
 
 public class SctpNet {
     static final String osName = AccessController.doPrivileged(
--- a/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SctpServerChannelImpl.java	Wed May 18 13:19:32 2011 +0200
@@ -40,7 +40,7 @@
 import com.sun.nio.sctp.SctpChannel;
 import com.sun.nio.sctp.SctpServerChannel;
 import com.sun.nio.sctp.SctpSocketOption;
-import com.sun.nio.sctp.SctpStandardSocketOption;
+import com.sun.nio.sctp.SctpStandardSocketOptions;
 
 /**
  * An implementation of SctpServerChannel
@@ -386,7 +386,7 @@
 
         private static Set<SctpSocketOption<?>> defaultOptions() {
             HashSet<SctpSocketOption<?>> set = new HashSet<SctpSocketOption<?>>(1);
-            set.add(SctpStandardSocketOption.SCTP_INIT_MAXSTREAMS);
+            set.add(SctpStandardSocketOptions.SCTP_INIT_MAXSTREAMS);
             return Collections.unmodifiableSet(set);
         }
     }
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java	Wed May 18 13:19:32 2011 +0200
@@ -210,15 +210,15 @@
 
             int mask = 0;
             for (WatchEvent.Kind<?> event: events) {
-                if (event == StandardWatchEventKind.ENTRY_CREATE) {
+                if (event == StandardWatchEventKinds.ENTRY_CREATE) {
                     mask |= IN_CREATE | IN_MOVED_TO;
                     continue;
                 }
-                if (event == StandardWatchEventKind.ENTRY_DELETE) {
+                if (event == StandardWatchEventKinds.ENTRY_DELETE) {
                     mask |= IN_DELETE | IN_MOVED_FROM;
                     continue;
                 }
-                if (event == StandardWatchEventKind.ENTRY_MODIFY) {
+                if (event == StandardWatchEventKinds.ENTRY_MODIFY) {
                     mask |= IN_MODIFY | IN_ATTRIB;
                     continue;
                 }
@@ -378,17 +378,17 @@
          */
         private WatchEvent.Kind<?> maskToEventKind(int mask) {
             if ((mask & IN_MODIFY) > 0)
-                return StandardWatchEventKind.ENTRY_MODIFY;
+                return StandardWatchEventKinds.ENTRY_MODIFY;
             if ((mask & IN_ATTRIB) > 0)
-                return StandardWatchEventKind.ENTRY_MODIFY;
+                return StandardWatchEventKinds.ENTRY_MODIFY;
             if ((mask & IN_CREATE) > 0)
-                return StandardWatchEventKind.ENTRY_CREATE;
+                return StandardWatchEventKinds.ENTRY_CREATE;
             if ((mask & IN_MOVED_TO) > 0)
-                return StandardWatchEventKind.ENTRY_CREATE;
+                return StandardWatchEventKinds.ENTRY_CREATE;
             if ((mask & IN_DELETE) > 0)
-                return StandardWatchEventKind.ENTRY_DELETE;
+                return StandardWatchEventKinds.ENTRY_DELETE;
             if ((mask & IN_MOVED_FROM) > 0)
-                return StandardWatchEventKind.ENTRY_DELETE;
+                return StandardWatchEventKinds.ENTRY_DELETE;
             return null;
         }
 
@@ -400,7 +400,7 @@
             if ((mask & IN_Q_OVERFLOW) > 0) {
                 for (Map.Entry<Integer,LinuxWatchKey> entry: wdToKey.entrySet()) {
                     entry.getValue()
-                        .signalEvent(StandardWatchEventKind.OVERFLOW, null);
+                        .signalEvent(StandardWatchEventKinds.OVERFLOW, null);
                 }
                 return;
             }
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java	Wed May 18 13:19:32 2011 +0200
@@ -486,7 +486,7 @@
         void processDirectoryEvents(SolarisWatchKey key, int mask) {
             if ((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) {
                 registerChildren(key.getDirectory(), key,
-                    key.events().contains(StandardWatchEventKind.ENTRY_CREATE));
+                    key.events().contains(StandardWatchEventKinds.ENTRY_CREATE));
             }
         }
 
@@ -504,14 +504,14 @@
 
             // entry modified
             if (((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) &&
-                events.contains(StandardWatchEventKind.ENTRY_MODIFY))
+                events.contains(StandardWatchEventKinds.ENTRY_MODIFY))
             {
-                key.signalEvent(StandardWatchEventKind.ENTRY_MODIFY, node.name());
+                key.signalEvent(StandardWatchEventKinds.ENTRY_MODIFY, node.name());
             }
 
             // entry removed
             if (((mask & (FILE_REMOVED)) != 0) &&
-                events.contains(StandardWatchEventKind.ENTRY_DELETE))
+                events.contains(StandardWatchEventKinds.ENTRY_DELETE))
             {
                 // Due to 6636438/6636412 we may get a remove event for cases
                 // where a rmdir/unlink/rename is attempted but fails. Until
@@ -527,7 +527,7 @@
                 } catch (UnixException x) { }
 
                 if (removed)
-                    key.signalEvent(StandardWatchEventKind.ENTRY_DELETE, node.name());
+                    key.signalEvent(StandardWatchEventKinds.ENTRY_DELETE, node.name());
             }
             return false;
         }
@@ -547,7 +547,7 @@
             // if the ENTRY_MODIFY event is not enabled then we don't need
             // modification events for entries in the directory
             int events = FILE_NOFOLLOW;
-            if (parent.events().contains(StandardWatchEventKind.ENTRY_MODIFY))
+            if (parent.events().contains(StandardWatchEventKinds.ENTRY_MODIFY))
                 events |= (FILE_MODIFIED | FILE_ATTRIB);
 
             DirectoryStream<Path> stream = null;
@@ -567,7 +567,7 @@
 
                     // send ENTRY_CREATE if enabled
                     if (sendEvents) {
-                        parent.signalEvent(StandardWatchEventKind.ENTRY_CREATE, name);
+                        parent.signalEvent(StandardWatchEventKinds.ENTRY_CREATE, name);
                     }
 
                     // register it
@@ -602,12 +602,12 @@
             // update events, rembering if ENTRY_MODIFY was previously
             // enabled or disabled.
             boolean wasModifyEnabled = key.events()
-                .contains(StandardWatchEventKind.ENTRY_MODIFY);
+                .contains(StandardWatchEventKinds.ENTRY_MODIFY);
             key.setEvents(events);
 
             // check if ENTRY_MODIFY has changed
             boolean isModifyEnabled = events
-                .contains(StandardWatchEventKind.ENTRY_MODIFY);
+                .contains(StandardWatchEventKinds.ENTRY_MODIFY);
             if (wasModifyEnabled == isModifyEnabled) {
                 return;
             }
--- a/jdk/src/solaris/native/sun/awt/awt_Robot.c	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/native/sun/awt/awt_Robot.c	Wed May 18 13:19:32 2011 +0200
@@ -48,28 +48,12 @@
 #ifdef __linux__
 #include <sys/socket.h>
 #endif
-#include <dlfcn.h>
 
 extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
 
 static jint * masks;
 static jint num_buttons;
 
-static unsigned int s_robotInstanceCounter = 0;
-
-static void* xcompositeLibHandle = NULL;
-static Bool xcompositeExtAvailable = False;
-static Bool xcompositeExtTested = False;
-
-typedef Status (*T_XCompositeQueryVersion)(Display *dpy, int *major_versionp, int *minor_versionp);
-typedef Window (*T_XCompositeGetOverlayWindow)(Display *dpy, Window window);
-typedef void (*T_XCompositeReleaseOverlayWindow)(Display *dpy, Window window);
-
-static T_XCompositeQueryVersion XCompositeQueryVersion = NULL;
-static T_XCompositeGetOverlayWindow XCompositeGetOverlayWindow = NULL;
-static T_XCompositeReleaseOverlayWindow XCompositeReleaseOverlayWindow = NULL;
-
-
 static int32_t isXTestAvailable() {
     int32_t major_opcode, first_event, first_error;
     int32_t  event_basep, error_basep, majorp, minorp;
@@ -210,80 +194,8 @@
     }
 
     AWT_UNLOCK();
-
-    s_robotInstanceCounter++;
-}
-
-JNIEXPORT void JNICALL
-Java_sun_awt_X11_XRobotPeer__1dispose (JNIEnv * env, jclass cls)
-{
-    if (--s_robotInstanceCounter) {
-        return;
-    }
-
-    // This is the last instance of the XRobotPeer being released
-
-    if (xcompositeExtTested && xcompositeExtAvailable && xcompositeLibHandle) {
-        // The lib is loaded in IsXCompositeAvailable(). Unload under AWT_LOCK
-        // so that the shutdown function of the lib behaves correctly.
-        AWT_LOCK();
-        dlclose(xcompositeLibHandle);
-        AWT_UNLOCK();
-    }
-
-    xcompositeExtTested = False;
-    xcompositeExtAvailable = False;
-    xcompositeLibHandle = NULL;
 }
 
-/*
- * Returns True only if XCOMPOSITE is of version 0.3 or higher.
- * The functions that we need are available since that version.
- *
- * Must be invoked under AWT_LOCK.
- *
- * Leaves the library loaded if the version is correct.
- */
-static Bool IsXCompositeAvailable()
-{
-    if (!xcompositeExtTested) {
-        int opcode, eventb, errorb;
-
-        if (XQueryExtension(awt_display, "Composite", &opcode, &eventb, &errorb)) {
-            xcompositeLibHandle = dlopen("libXcomposite.so.1", RTLD_LAZY | RTLD_GLOBAL);
-#ifndef __linux__ /* SOLARIS */
-            if (xcompositeLibHandle == NULL) {
-                xcompositeLibHandle = dlopen("/usr/sfw/lib/libXcomposite.so.1",
-                        RTLD_LAZY | RTLD_GLOBAL);
-            }
-#endif
-
-            if (xcompositeLibHandle) {
-                int major, minor;
-                XCompositeQueryVersion = (T_XCompositeQueryVersion)dlsym(xcompositeLibHandle, "XCompositeQueryVersion");
-
-                if (XCompositeQueryVersion && XCompositeQueryVersion(awt_display, &major, &minor)) {
-                    if (major >= 0 && minor >= 3) {
-                        XCompositeGetOverlayWindow = (T_XCompositeGetOverlayWindow)dlsym(xcompositeLibHandle, "XCompositeGetOverlayWindow");
-                        XCompositeReleaseOverlayWindow = (T_XCompositeReleaseOverlayWindow)dlsym(xcompositeLibHandle, "XCompositeReleaseOverlayWindow");
-
-                        if (XCompositeGetOverlayWindow && XCompositeReleaseOverlayWindow) {
-                            xcompositeExtAvailable = True;
-                        }
-                    }
-                }
-
-                if (!xcompositeExtAvailable) {
-                    dlclose(xcompositeLibHandle);
-                } /* else the lib is unloaded in _dispose() */
-            }
-        }
-
-        xcompositeExtTested = True;
-    }
-
-    return xcompositeExtAvailable;
-}
 
 JNIEXPORT void JNICALL
 Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl( JNIEnv *env,
@@ -299,7 +211,7 @@
     jint *ary;               /* Array of jints for sending pixel values back
                               * to parent process.
                               */
-    Window window;
+    Window rootWindow;
     AwtGraphicsConfigDataPtr adata;
 
     DTRACE_PRINTLN6("RobotPeer: getRGBPixelsImpl(%lx, %d, %d, %d, %d, %x)", xgc, x, y, width, height, pixelArray);
@@ -316,24 +228,14 @@
     adata = (AwtGraphicsConfigDataPtr) JNU_GetLongFieldAsPtr(env, xgc, x11GraphicsConfigIDs.aData);
     DASSERT(adata != NULL);
 
-    window = XRootWindow(awt_display, adata->awt_visInfo.screen);
-
-    if (IsXCompositeAvailable()) {
-        // Use 'composite overlay window' instead of the root window.
-        // See 6903034 for details.
-        window = XCompositeGetOverlayWindow(awt_display, window);
-    }
-
-    image = getWindowImage(awt_display, window, x, y, width, height);
+    rootWindow = XRootWindow(awt_display, adata->awt_visInfo.screen);
+    image = getWindowImage(awt_display, rootWindow, x, y, width, height);
 
     /* Array to use to crunch around the pixel values */
     ary = (jint *) malloc(width * height * sizeof (jint));
     if (ary == NULL) {
         JNU_ThrowOutOfMemoryError(env, "OutOfMemoryError");
         XDestroyImage(image);
-        if (IsXCompositeAvailable()) {
-            XCompositeReleaseOverlayWindow(awt_display, window);
-        }
         AWT_UNLOCK();
         return;
     }
@@ -354,9 +256,6 @@
     free(ary);
 
     XDestroyImage(image);
-    if (IsXCompositeAvailable()) {
-        XCompositeReleaseOverlayWindow(awt_display, window);
-    }
 
     AWT_UNLOCK();
 }
--- a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c	Wed May 18 13:19:32 2011 +0200
@@ -892,8 +892,9 @@
 
         if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
             /* not found or error */
-            if (errno != 0 && errno != ENOENT)
-                throwUnixException(env, errno);
+            if (errno == 0)
+                errno = ENOENT;
+            throwUnixException(env, errno);
         } else {
             jsize len = strlen(p->pw_name);
             result = (*env)->NewByteArray(env, len);
@@ -941,14 +942,14 @@
         retry = 0;
         if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
             /* not found or error */
-            if (errno != 0 && errno != ENOENT) {
-                if (errno == ERANGE) {
-                    /* insufficient buffer size so need larger buffer */
-                    buflen += ENT_BUF_SIZE;
-                    retry = 1;
-                } else {
-                    throwUnixException(env, errno);
-                }
+            if (errno == ERANGE) {
+                /* insufficient buffer size so need larger buffer */
+                buflen += ENT_BUF_SIZE;
+                retry = 1;
+            } else {
+                if (errno == 0)
+                    errno = ENOENT;
+                throwUnixException(env, errno);
             }
         } else {
             jsize len = strlen(g->gr_name);
--- a/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java	Wed May 18 13:19:32 2011 +0200
@@ -107,8 +107,16 @@
             Rectangle currentDevBounds = currentDevGC.getBounds();
             Rectangle primaryDevBounds = primaryDevGC.getBounds();
 
-            b.width -= (currentDevBounds.width - primaryDevBounds.width);
-            b.height -= (currentDevBounds.height - primaryDevBounds.height);
+            boolean isCurrentDevLarger =
+                ((currentDevBounds.width - primaryDevBounds.width > 0) ||
+                 (currentDevBounds.height - primaryDevBounds.height > 0));
+
+            // the window manager doesn't seem to compensate for differences when
+            // the primary monitor is larger than the monitor that display the window
+            if (isCurrentDevLarger) {
+                b.width -= (currentDevBounds.width - primaryDevBounds.width);
+                b.height -= (currentDevBounds.height - primaryDevBounds.height);
+            }
         }
     }
 
--- a/jdk/src/windows/classes/sun/java2d/d3d/D3DRenderer.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DRenderer.java	Wed May 18 13:19:32 2011 +0200
@@ -102,15 +102,20 @@
             final ParallelogramPipe realpipe = d3dr.getAAParallelogramPipe();
             return new ParallelogramPipe() {
                 public void fillParallelogram(SunGraphics2D sg2d,
+                                              double ux1, double uy1,
+                                              double ux2, double uy2,
                                               double x, double y,
                                               double dx1, double dy1,
                                               double dx2, double dy2)
                 {
                     GraphicsPrimitive.tracePrimitive("D3DFillAAParallelogram");
                     realpipe.fillParallelogram(sg2d,
+                                               ux1, uy1, ux2, uy2,
                                                x, y, dx1, dy1, dx2, dy2);
                 }
                 public void drawParallelogram(SunGraphics2D sg2d,
+                                              double ux1, double uy1,
+                                              double ux2, double uy2,
                                               double x, double y,
                                               double dx1, double dy1,
                                               double dx2, double dy2,
@@ -118,6 +123,7 @@
                 {
                     GraphicsPrimitive.tracePrimitive("D3DDrawAAParallelogram");
                     realpipe.drawParallelogram(sg2d,
+                                               ux1, uy1, ux2, uy2,
                                                x, y, dx1, dy1, dx2, dy2,
                                                lw1, lw2);
                 }
@@ -167,21 +173,29 @@
             d3dr.fillSpans(sg2d, si, transx, transy);
         }
         public void fillParallelogram(SunGraphics2D sg2d,
+                                      double ux1, double uy1,
+                                      double ux2, double uy2,
                                       double x, double y,
                                       double dx1, double dy1,
                                       double dx2, double dy2)
         {
             GraphicsPrimitive.tracePrimitive("D3DFillParallelogram");
-            d3dr.fillParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2);
+            d3dr.fillParallelogram(sg2d,
+                                   ux1, uy1, ux2, uy2,
+                                   x, y, dx1, dy1, dx2, dy2);
         }
         public void drawParallelogram(SunGraphics2D sg2d,
+                                      double ux1, double uy1,
+                                      double ux2, double uy2,
                                       double x, double y,
                                       double dx1, double dy1,
                                       double dx2, double dy2,
                                       double lw1, double lw2)
         {
             GraphicsPrimitive.tracePrimitive("D3DDrawParallelogram");
-            d3dr.drawParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2, lw1, lw2);
+            d3dr.drawParallelogram(sg2d,
+                                   ux1, uy1, ux2, uy2,
+                                   x, y, dx1, dy1, dx2, dy2, lw1, lw2);
         }
         public void copyArea(SunGraphics2D sg2d,
                              int x, int y, int w, int h, int dx, int dy)
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsWatchService.java	Wed May 18 13:19:32 2011 +0200
@@ -464,15 +464,15 @@
         {
             switch (action) {
                 case FILE_ACTION_MODIFIED :
-                    return StandardWatchEventKind.ENTRY_MODIFY;
+                    return StandardWatchEventKinds.ENTRY_MODIFY;
 
                 case FILE_ACTION_ADDED :
                 case FILE_ACTION_RENAMED_NEW_NAME :
-                    return StandardWatchEventKind.ENTRY_CREATE;
+                    return StandardWatchEventKinds.ENTRY_CREATE;
 
                 case FILE_ACTION_REMOVED :
                 case FILE_ACTION_RENAMED_OLD_NAME :
-                    return StandardWatchEventKind.ENTRY_DELETE;
+                    return StandardWatchEventKinds.ENTRY_DELETE;
 
                 default :
                     return null;  // action not recognized
@@ -548,7 +548,7 @@
                 if (info.error() != 0) {
                     // buffer overflow
                     if (info.error() == ERROR_NOTIFY_ENUM_DIR) {
-                        key.signalEvent(StandardWatchEventKind.OVERFLOW, null);
+                        key.signalEvent(StandardWatchEventKinds.OVERFLOW, null);
                     } else {
                         // other error so cancel key
                         implCancelKey(key);
@@ -562,7 +562,7 @@
                     processEvents(key, info.bytesTransferred());
                 } else {
                     // insufficient buffer size
-                    key.signalEvent(StandardWatchEventKind.OVERFLOW, null);
+                    key.signalEvent(StandardWatchEventKinds.OVERFLOW, null);
                 }
 
                 // start read for next batch of changes
--- a/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp	Wed May 18 13:19:32 2011 +0200
@@ -192,6 +192,14 @@
     pMgr = D3DPipelineManager::GetInstance();
     RETURN_IF_NULL(pMgr);
     hMon = pMgr->pd3d9->GetAdapterMonitor(adapter);
+
+    /*
+     * If we don't have devices initialized yet, no sense to clear them.
+     */
+    if (!Devices::GetInstance()){
+         return;
+    }
+
     gdiScreen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hMon);
 
     JNU_CallStaticMethodByName(env, NULL,
--- a/jdk/src/windows/native/sun/security/mscapi/security.cpp	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/native/sun/security/mscapi/security.cpp	Wed May 18 13:19:32 2011 +0200
@@ -705,7 +705,7 @@
     HCRYPTPROV hCryptProv = NULL;
     HCRYPTKEY hKeyPair;
     DWORD dwFlags = (keySize << 16) | CRYPT_EXPORTABLE;
-    jobject keypair;
+    jobject keypair = NULL;
     const char* pszKeyContainerName = NULL; // UUID
 
     __try
--- a/jdk/src/windows/native/sun/windows/Devices.h	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/Devices.h	Wed May 18 13:19:32 2011 +0200
@@ -36,6 +36,7 @@
 class Devices {
 
 public:
+static Devices*                 GetInstance();
 static BOOL                     UpdateInstance(JNIEnv *env);
        int                      GetNumDevices() { return numDevices; }
        AwtWin32GraphicsDevice*  GetDeviceReference(int index, BOOL adjust = TRUE);
@@ -59,7 +60,6 @@
 private:
                                 Devices(int numElements);
        void                     AddReference();
-static Devices*                 GetInstance();
 
        AwtWin32GraphicsDevice** devices;
        int                      refCount;
--- a/jdk/src/windows/native/sun/windows/awt_Choice.cpp	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Choice.cpp	Wed May 18 13:19:32 2011 +0200
@@ -396,6 +396,12 @@
 
     DASSERT(::IsWindow(hwnd));
 
+    // This branch is required for the proper work of AwtComponent::GetComponent() method
+    // while hovering drop-down list
+    if (message == WmAwtIsComponent) {
+        return (LRESULT)TRUE;
+    }
+
     switch (message) {
         case WM_LBUTTONDOWN: {
             DWORD curPos = ::GetMessagePos();
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp	Wed May 18 13:19:32 2011 +0200
@@ -364,7 +364,6 @@
     AwtComponent *component =
         (AwtComponent *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
     DASSERT(!component || !IsBadReadPtr(component, sizeof(AwtComponent)) );
-    DASSERT(!component || component->GetHWnd() == hWnd );
     return component;
 }
 
--- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp	Wed May 18 13:19:32 2011 +0200
@@ -344,17 +344,6 @@
                 SetImeTargetComponent(NULL);
             }
             break;
-        // TODO: when a Choice's list is dropped down and we're scrolling in
-        // the list WM_MOUSEWHEEL messages come to the poxy, not to the list. Why?
-        case WM_MOUSEWHEEL:
-            focusOwner = AwtComponent::GetComponent(sm_focusOwner);
-            if  (focusOwner != NULL &&
-                 focusOwner != this) // avoid recursive calls
-            {
-                 retValue = focusOwner->WindowProc(message, wParam, lParam);
-                 mr = mrConsume;
-            }
-            break;
         case WM_SETFOCUS:
             if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain
 
--- a/jdk/test/ProblemList.txt	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/ProblemList.txt	Wed May 18 13:19:32 2011 +0200
@@ -195,6 +195,9 @@
 
 # jdk_lang
 
+# requires junit
+java/lang/invoke/InvokeDynamicPrintArgs.java                    generic-all
+
 # Times out on solaris 10 sparc
 java/lang/ClassLoader/Assert.java				generic-all
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/GarbageCollectorMXBean/GarbageCollectionNotificationContentTest.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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     7036199
+ * @summary Check that GarbageCollectionNotification contents are reasonable
+ * @author  Frederic Parain
+ * @run     main/othervm GarbageCollectionNotificationContentTest
+ */
+
+import java.util.*;
+import java.lang.management.*;
+import java.lang.reflect.*;
+import javax.management.*;
+import javax.management.openmbean.*;
+import com.sun.management.GarbageCollectionNotificationInfo;
+import com.sun.management.GcInfo;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.lang.reflect.Field;
+
+public class GarbageCollectionNotificationContentTest {
+    private static HashMap<String,GarbageCollectionNotificationInfo> listenerInvoked
+        = new HashMap<String,GarbageCollectionNotificationInfo>();
+    static volatile long count = 0;
+    static volatile long number = 0;
+    static Object synchronizer = new Object();
+
+    static class GcListener implements NotificationListener {
+        public void handleNotification(Notification notif, Object handback) {
+            String type = notif.getType();
+            if (type.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
+                GarbageCollectionNotificationInfo gcNotif =
+                    GarbageCollectionNotificationInfo.from((CompositeData) notif.getUserData());
+                String source = ((ObjectName)notif.getSource()).getCanonicalName();
+                synchronized(synchronizer) {
+                    if(listenerInvoked.get(source) == null) {
+                            listenerInvoked.put(((ObjectName)notif.getSource()).getCanonicalName(),gcNotif);
+                            count++;
+                            if(count >= number) {
+                                synchronizer.notify();
+                            }
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        final Boolean isNotificationSupported = AccessController.doPrivileged (new PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    try {
+                        Class cl = Class.forName("sun.management.VMManagementImpl");
+                        Field f = cl.getDeclaredField("gcNotificationSupport");
+                        f.setAccessible(true);
+                        return f.getBoolean(null);
+                    } catch(ClassNotFoundException e) {
+                        return false;
+                    } catch(NoSuchFieldException e) {
+                        return false;
+                    } catch(IllegalAccessException e) {
+                        return false;
+                    }
+                }
+            });
+        if(!isNotificationSupported) {
+            System.out.println("GC Notification not supported by the JVM, test skipped");
+            return;
+        }
+        final ObjectName gcMXBeanPattern =
+                new ObjectName("java.lang:type=GarbageCollector,*");
+        Set<ObjectName> names =
+                mbs.queryNames(gcMXBeanPattern, null);
+        if (names.isEmpty())
+            throw new Exception("Test incorrect: no GC MXBeans");
+        number = names.size();
+        for (ObjectName n : names) {
+            if(mbs.isInstanceOf(n,"javax.management.NotificationEmitter")) {
+                listenerInvoked.put(n.getCanonicalName(),null);
+                GcListener listener = new GcListener();
+                mbs.addNotificationListener(n, listener, null, null);
+            }
+        }
+        // Invocation of System.gc() to trigger major GC
+        System.gc();
+        // Allocation of many short living and small objects to trigger minor GC
+        Object data[] = new Object[32];
+        for(int i = 0; i<100000000; i++) {
+            data[i%32] = new int[8];
+        }
+        int wakeup = 0;
+        synchronized(synchronizer) {
+            while(count != number) {
+                synchronizer.wait(10000);
+                wakeup++;
+                if(wakeup > 10)
+                    break;
+            }
+        }
+        for (GarbageCollectionNotificationInfo notif : listenerInvoked.values() ) {
+            checkGarbageCollectionNotificationInfoContent(notif);
+        }
+        System.out.println("Test passed");
+    }
+
+    private static void checkGarbageCollectionNotificationInfoContent(GarbageCollectionNotificationInfo notif) throws Exception {
+        System.out.println("GC notification for "+notif.getGcName());
+        System.out.print("Action: "+notif.getGcAction());
+        System.out.println(" Cause: "+notif.getGcCause());
+        GcInfo info = notif.getGcInfo();
+        System.out.print("GC Info #" + info.getId());
+        System.out.print(" start:" + info.getStartTime());
+        System.out.print(" end:" + info.getEndTime());
+        System.out.println(" (" + info.getDuration() + "ms)");
+        Map<String, MemoryUsage> usage = info.getMemoryUsageBeforeGc();
+
+        List<String> pnames = new ArrayList<String>();
+        for (Map.Entry entry : usage.entrySet() ) {
+            String poolname = (String) entry.getKey();
+            pnames.add(poolname);
+            MemoryUsage busage = (MemoryUsage) entry.getValue();
+            MemoryUsage ausage = (MemoryUsage) info.getMemoryUsageAfterGc().get(poolname);
+            if (ausage == null) {
+                throw new RuntimeException("After Gc Memory does not exist" +
+                    " for " + poolname);
+            }
+            System.out.println("Usage for pool " + poolname);
+            System.out.println("   Before GC: " + busage);
+            System.out.println("   After GC: " + ausage);
+        }
+
+        // check if memory usage for all memory pools are returned
+        List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
+        for (MemoryPoolMXBean p : pools ) {
+            if (!pnames.contains(p.getName())) {
+                throw new RuntimeException("GcInfo does not contain " +
+                    "memory usage for pool " + p.getName());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/GarbageCollectorMXBean/GarbageCollectionNotificationTest.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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     7036199
+ * @summary Check that GarbageCollection notification are thrown by every GarbageCollectorMXBean
+ * @author  Frederic Parain
+ * @run     main/othervm GarbageCollectionNotificationTest
+ */
+
+import java.util.*;
+import java.lang.management.*;
+import java.lang.reflect.*;
+import javax.management.*;
+import javax.management.openmbean.*;
+import com.sun.management.GarbageCollectionNotificationInfo;
+import com.sun.management.GcInfo;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.lang.reflect.Field;
+
+public class GarbageCollectionNotificationTest {
+    private static HashMap<String,Boolean> listenerInvoked = new HashMap<String,Boolean>();
+    static volatile long count = 0;
+    static volatile long number = 0;
+    static Object synchronizer = new Object();
+
+    static class GcListener implements NotificationListener {
+        public void handleNotification(Notification notif, Object handback) {
+            String type = notif.getType();
+            if (type.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
+                GarbageCollectionNotificationInfo gcNotif =
+                    GarbageCollectionNotificationInfo.from((CompositeData) notif.getUserData());
+                String source = ((ObjectName)notif.getSource()).getCanonicalName();
+                synchronized(synchronizer) {
+                    if(!listenerInvoked.get(source)) {
+                            listenerInvoked.put(((ObjectName)notif.getSource()).getCanonicalName(),true);
+                            count++;
+                            if(count >= number) {
+                                synchronizer.notify();
+                            }
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        final Boolean isNotificationSupported = AccessController.doPrivileged (new PrivilegedAction<Boolean>() {
+                public Boolean run() {
+                    try {
+                        Class cl = Class.forName("sun.management.VMManagementImpl");
+                        Field f = cl.getDeclaredField("gcNotificationSupport");
+                        f.setAccessible(true);
+                        return f.getBoolean(null);
+                    } catch(ClassNotFoundException e) {
+                        return false;
+                    } catch(NoSuchFieldException e) {
+                        return false;
+                    } catch(IllegalAccessException e) {
+                        return false;
+                    }
+                }
+            });
+        if(!isNotificationSupported) {
+            System.out.println("GC Notification not supported by the JVM, test skipped");
+            return;
+        }
+        final ObjectName gcMXBeanPattern =
+                new ObjectName("java.lang:type=GarbageCollector,*");
+        Set<ObjectName> names =
+                mbs.queryNames(gcMXBeanPattern, null);
+        if (names.isEmpty())
+            throw new Exception("Test incorrect: no GC MXBeans");
+        number = names.size();
+        for (ObjectName n : names) {
+            if(mbs.isInstanceOf(n,"javax.management.NotificationEmitter")) {
+                listenerInvoked.put(n.getCanonicalName(),false);
+                GcListener listener = new GcListener();
+                mbs.addNotificationListener(n, listener, null, null);
+            }
+        }
+        // Invocation of System.gc() to trigger major GC
+        System.gc();
+        // Allocation of many short living and small objects to trigger minor GC
+        Object data[] = new Object[32];
+        for(int i = 0; i<100000000; i++) {
+            data[i%32] = new int[8];
+        }
+        int wakeup = 0;
+        synchronized(synchronizer) {
+            while(count != number) {
+                synchronizer.wait(10000);
+                wakeup++;
+                if(wakeup > 10)
+                    break;
+            }
+        }
+        for (String source : listenerInvoked.keySet()) {
+            if(!listenerInvoked.get(source))
+                throw new Exception("Test incorrect: notifications have not been sent for "
+                                    + source);
+        }
+        System.out.println("Test passed");
+    }
+}
--- a/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/com/sun/nio/sctp/SctpChannel/SocketOptionTests.java	Wed May 18 13:19:32 2011 +0200
@@ -40,7 +40,7 @@
 import com.sun.nio.sctp.SctpSocketOption;
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
-import static com.sun.nio.sctp.SctpStandardSocketOption.*;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
 import static java.lang.System.out;
 
 public class SocketOptionTests {
--- a/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/com/sun/nio/sctp/SctpMultiChannel/SocketOptionTests.java	Wed May 18 13:19:32 2011 +0200
@@ -48,7 +48,7 @@
 import com.sun.nio.sctp.SctpSocketOption;
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
-import static com.sun.nio.sctp.SctpStandardSocketOption.*;
+import static com.sun.nio.sctp.SctpStandardSocketOptions.*;
 import static java.lang.System.out;
 
 public class SocketOptionTests {
--- a/jdk/test/java/awt/Component/Revalidate/Revalidate.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/awt/Component/Revalidate/Revalidate.java	Wed May 18 13:19:32 2011 +0200
@@ -26,7 +26,7 @@
   @bug 7036669
   @summary Test Component.revalidate() method
   @author anthony.petrov@oracle.com: area=awt.component
-  @run main Revalidate
+  @run main/othervm -Djava.awt.smartInvalidate=true Revalidate
 */
 
 import java.awt.*;
--- a/jdk/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/awt/Container/ValidateRoot/InvalidateMustRespectValidateRoots.java	Wed May 18 13:19:32 2011 +0200
@@ -26,7 +26,7 @@
   @bug 6852592
   @summary invalidate() must stop when it encounters a validate root
   @author anthony.petrov@sun.com
-  @run main InvalidateMustRespectValidateRoots
+  @run main/othervm -Djava.awt.smartInvalidate=true InvalidateMustRespectValidateRoots
 */
 
 import javax.swing.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Paint/PgramUserBoundsTest.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7043054
+ * @summary Verifies that Paint objects receive the appropriate user space
+ *          bounds in their createContext() method
+ * @run main PgramUserBoundsTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.PaintContext;
+import java.awt.RenderingHints;
+import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+
+public class PgramUserBoundsTest {
+    static final int MinX = 10;
+    static final int MinY = 20;
+    static final int MaxX = 30;
+    static final int MaxY = 50;
+    static AffineTransform identity = new AffineTransform();
+
+    public static void main(String argv[]) {
+        BufferedImage bimg =
+            new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2d = bimg.createGraphics();
+        g2d.setPaint(new BoundsCheckerPaint(MinX, MinY, MaxX, MaxY));
+        testAll(g2d);
+        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                             RenderingHints.VALUE_ANTIALIAS_ON);
+        testAll(g2d);
+    }
+
+    static void testAll(Graphics2D g2d) {
+        g2d.setTransform(identity);
+        g2d.translate(100, 100);
+        testPrimitives(g2d);
+
+        g2d.setTransform(identity);
+        g2d.scale(10, 10);
+        testPrimitives(g2d);
+
+        g2d.setTransform(identity);
+        g2d.rotate(Math.PI/6);
+        testPrimitives(g2d);
+    }
+
+    static void testPrimitives(Graphics2D g2d) {
+        testLine(g2d);
+        testRect(g2d);
+    }
+
+    static void testLine(Graphics2D g2d) {
+        testLine(g2d, MinX, MinY, MaxX, MaxY);
+        testLine(g2d, MaxX, MinY, MinX, MaxY);
+        testLine(g2d, MinX, MaxY, MaxX, MinY);
+        testLine(g2d, MaxX, MaxY, MinX, MinY);
+    }
+
+    static void testRect(Graphics2D g2d) {
+        g2d.fillRect(MinX, MinY, MaxX - MinX, MaxY - MinY);
+        g2d.fill(new Rectangle(MinX, MinY, MaxX - MinX, MaxY - MinY));
+    }
+
+    static void testLine(Graphics2D g2d, int x1, int y1, int x2, int y2) {
+        g2d.drawLine(x1, y1, x2, y2);
+        g2d.draw(new Line2D.Double(x1, y1, x2, y2));
+    }
+
+    static class BoundsCheckerPaint implements Paint {
+        private Color c = Color.WHITE;
+        private Rectangle2D expectedBounds;
+
+        public BoundsCheckerPaint(double x1, double y1,
+                                  double x2, double y2)
+        {
+            expectedBounds = new Rectangle2D.Double();
+            expectedBounds.setFrameFromDiagonal(x1, y1, x2, y2);
+        }
+
+        public int getTransparency() {
+            return c.getTransparency();
+        }
+
+        public PaintContext createContext(ColorModel cm,
+                                          Rectangle deviceBounds,
+                                          Rectangle2D userBounds,
+                                          AffineTransform xform,
+                                          RenderingHints hints)
+        {
+            System.out.println("user bounds = "+userBounds);
+            if (!userBounds.equals(expectedBounds)) {
+                throw new RuntimeException("bounds fail to match");
+            }
+            return c.createContext(cm, deviceBounds, userBounds, xform, hints);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Toolkit/Headless/ExceptionContract/ExceptionContract.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/*
+  @test
+  @bug 7040577
+  @library ../../../regtesthelpers
+  @build Sysout
+  @summary Default implementation of Toolkit.loadSystemColors(int[]) and many others doesn't throw HE in hl env
+  @author andrei dmitriev: area=awt.headless
+  @run main/othervm -Djava.awt.headless=true ExceptionContract
+*/
+
+import java.awt.*;
+import java.util.Properties;
+import test.java.awt.regtesthelpers.Sysout;
+
+import java.awt.datatransfer.Clipboard;
+import java.awt.dnd.*;
+import java.awt.dnd.peer.DragSourceContextPeer;
+import java.awt.font.TextAttribute;
+import java.awt.im.InputMethodHighlight;
+import java.awt.image.*;
+import java.awt.peer.*;
+import java.net.URL;
+import java.util.Map;
+import java.util.Properties;
+
+public class ExceptionContract {
+
+    private static boolean passed = false;
+    public static void main(String[] args)  {
+        //Case1
+        try{
+            new _Toolkit().getLockingKeyState(1);
+        } catch (HeadlessException he){
+            passed = true;
+        }
+        if (!passed){
+            throw new RuntimeException("Tk.getLockingKeyState() didn't throw HeadlessException while in the headless mode.");
+        }
+
+        passed = false;
+        //Case2
+        try{
+            new _Toolkit().setLockingKeyState(1, true);
+        } catch (HeadlessException he){
+            passed = true;
+        }
+        if (!passed){
+            throw new RuntimeException("Tk.setLockingKeyState() didn't throw HeadlessException while in the headless mode.");
+        }
+
+        passed = false;
+        //Case3
+        try{
+            new _Toolkit().createCustomCursor(new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB), new Point(0,0), "Custom cursor");
+        } catch (HeadlessException he){
+            he.printStackTrace();
+            passed = true;
+        }
+        if (!passed){
+            throw new RuntimeException("Tk.createCustomCursor(args) didn't throw HeadlessException while in the headless mode.");
+        }
+
+    }
+
+    static class _Toolkit extends Toolkit {
+
+        @Override
+        public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
+            throws IndexOutOfBoundsException, HeadlessException
+        {
+            return super.createCustomCursor(cursor, hotSpot, name);
+        }
+
+
+        @Override
+        public void setLockingKeyState(int keyCode, boolean on) throws UnsupportedOperationException {
+            super.setLockingKeyState(keyCode, on);
+        }
+
+        @Override
+        public boolean getLockingKeyState(int keyCode) throws UnsupportedOperationException {
+            return super.getLockingKeyState(keyCode);
+        }
+
+
+        @Override
+        public void loadSystemColors(int[] systemColors) throws HeadlessException {
+            return;
+        }
+
+        @Override
+        protected DesktopPeer createDesktopPeer(Desktop target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected ButtonPeer createButton(Button target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected TextFieldPeer createTextField(TextField target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected LabelPeer createLabel(Label target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected ListPeer createList(List target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected CheckboxPeer createCheckbox(Checkbox target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected ScrollbarPeer createScrollbar(Scrollbar target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected ScrollPanePeer createScrollPane(ScrollPane target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected TextAreaPeer createTextArea(TextArea target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected ChoicePeer createChoice(Choice target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected FramePeer createFrame(Frame target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected CanvasPeer createCanvas(Canvas target) {
+            return null;
+        }
+
+        @Override
+        protected PanelPeer createPanel(Panel target) {
+            return null;
+        }
+
+        @Override
+        protected WindowPeer createWindow(Window target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected DialogPeer createDialog(Dialog target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected MenuBarPeer createMenuBar(MenuBar target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected MenuPeer createMenu(Menu target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected PopupMenuPeer createPopupMenu(PopupMenu target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected MenuItemPeer createMenuItem(MenuItem target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected FileDialogPeer createFileDialog(FileDialog target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target) throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected FontPeer getFontPeer(String name, int style) {
+            return null;
+        }
+
+        @Override
+        public Dimension getScreenSize() throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        public int getScreenResolution() throws HeadlessException {
+            return 0;
+        }
+
+        @Override
+        public ColorModel getColorModel() throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        public String[] getFontList() {
+            return new String[0];
+        }
+
+        @Override
+        public FontMetrics getFontMetrics(Font font) {
+            return null;
+        }
+
+        @Override
+        public void sync() {
+
+        }
+
+        @Override
+        public Image getImage(String filename) {
+            return null;
+        }
+
+        @Override
+        public Image getImage(URL url) {
+            return null;
+        }
+
+        @Override
+        public Image createImage(String filename) {
+            return null;
+        }
+
+        @Override
+        public Image createImage(URL url) {
+            return null;
+        }
+
+        @Override
+        public boolean prepareImage(Image image, int width, int height, ImageObserver observer) {
+            return false;
+        }
+
+        @Override
+        public int checkImage(Image image, int width, int height, ImageObserver observer) {
+            return 0;
+        }
+
+        @Override
+        public Image createImage(ImageProducer producer) {
+            return null;
+        }
+
+        @Override
+        public Image createImage(byte[] imagedata, int imageoffset, int imagelength) {
+            return null;
+        }
+
+        @Override
+        public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) {
+            return null;
+        }
+
+        @Override
+        public void beep() {
+
+        }
+
+        @Override
+        public Clipboard getSystemClipboard() throws HeadlessException {
+            return null;
+        }
+
+        @Override
+        protected EventQueue getSystemEventQueueImpl() {
+            return null;
+        }
+
+        @Override
+        public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
+            return null;
+        }
+
+        @Override
+        public boolean isModalityTypeSupported(Dialog.ModalityType modalityType) {
+            return false;
+        }
+
+        @Override
+        public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType modalExclusionType) {
+            return false;
+        }
+
+        @Override
+        public Map<TextAttribute, ?> mapInputMethodHighlight(InputMethodHighlight highlight) throws HeadlessException {
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/Arc2D/SerializationTest.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7040717 6522514
+ * @summary Verifies that subclasses of Arc2D can be serialized.
+ * @run main SerializationTest
+ */
+
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Arc2D;
+import java.io.Serializable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+public class SerializationTest {
+    static boolean failed;
+    public static void main(String args[]) {
+        test(new Arc());
+        test(new ArcF());
+        test(new ArcD());
+        if (failed) throw new RuntimeException("some tests failed");
+    }
+
+    public static void test(Object a) {
+        try {
+            File objectbin = new File("object.bin");
+            FileOutputStream fos = new FileOutputStream(objectbin);
+            ObjectOutputStream out = new ObjectOutputStream(fos);
+            out.writeObject(a);
+            fos.close();
+            FileInputStream fis = new FileInputStream(objectbin);
+            ObjectInputStream in = new ObjectInputStream(fis);
+            Object o = in.readObject();
+            fis.close();
+            System.err.println(o);
+        } catch (Throwable ex) {
+            ex.printStackTrace();
+            failed = true;
+        }
+    }
+
+    static class Arc extends Arc2D implements Serializable {
+        public Arc() {
+            super(Arc2D.OPEN);
+        }
+
+        public Rectangle2D makeBounds(double x, double y, double w, double h) {
+            return new Rectangle2D.Double(x, y, w, h);
+        }
+        public double getX() { return 0; }
+        public double getY() { return 0; }
+        public double getWidth() { return 0; }
+        public double getHeight() { return 0; }
+        public double getAngleExtent() { return 0; }
+        public double getAngleStart() { return 0; }
+        public void setAngleExtent(double angExt) { }
+        public void setAngleStart(double angExt) { }
+        public void setFrame(double x, double y, double w, double h) {}
+        public void setArc(double x, double y, double w, double h,
+                           double s, double e, int c)
+        {
+        }
+        public boolean isEmpty() { return false; };
+    }
+
+    static class ArcF extends Arc2D.Float implements Serializable {
+        public ArcF() {
+        }
+    }
+
+    static class ArcD extends Arc2D.Double implements Serializable {
+        public ArcD() {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/6998541/Test6998541.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 6998541
+ * @summary JSR 292 implement missing return-type conversion for OP_RETYPE_RAW
+ *
+ * @run main/othervm -Xbatch
+ *    -XX:+UnlockDiagnosticVMOptions -XX:ScavengeRootsInCode=2
+ *       -DTest6998541.N=100000 -DTest6998541.KIND=cast Test6998541
+ * @run main/othervm -Xbatch
+ *    -XX:+UnlockDiagnosticVMOptions -XX:ScavengeRootsInCode=2
+ *       -DTest6998541.N=100000 -DTest6998541.KIND=normal Test6998541
+ */
+
+import java.util.*;
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+
+public class Test6998541 {
+    private static final Class  CLASS = Test6998541.class;
+    private static final String NAME  = "identity";
+    private static final int    N     = Math.max(2, Integer.getInteger(CLASS.getSimpleName()+".N", 10000));
+    private static final String KIND  = System.getProperty(CLASS.getSimpleName()+".KIND", "cast");
+    private static final int    BITS  = 0x00000201;
+
+    private static final boolean DO_CASTS = !KIND.equals("normal");
+
+    public static void main(String[] args) throws Throwable {
+        System.out.println("KIND="+KIND+" DO_CASTS="+DO_CASTS+" N="+N);
+        doboolean();
+        dobyte();
+        dochar();
+        doshort();
+        doint();
+        dolong();
+        dofloat();
+        dodouble();
+        dovoid();
+    }
+
+    private static void doboolean() throws Throwable {
+        for (int i = 0; i < N; i++) {
+            boolean2prim(false);
+            boolean2prim(true);
+        }
+        boolean2prim_invalid(true);
+    }
+    private static void dobyte() throws Throwable {
+        byte x = Byte.MIN_VALUE;
+        for (int i = 0; i < N; i++, x++)
+            byte2prim(x);
+        byte2prim_invalid(x);
+    }
+    private static void dochar() throws Throwable {
+        char x = Character.MIN_VALUE;
+        for (int i = 0; i < N; i++, x++)
+            char2prim(x);
+        char2prim_invalid(x);
+    }
+    private static void doshort() throws Throwable {
+        short x = Short.MIN_VALUE;
+        for (int i = 0; i < N; i++, x++)
+            short2prim(x);
+        short2prim_invalid(x);
+    }
+    private static void doint() throws Throwable {
+        int x = Integer.MIN_VALUE;
+        int D = Integer.MAX_VALUE / (N / 2) | BITS;
+        for (int i = 0; i < N; i++, x += D) {
+            int2prim(x);
+        }
+        int2prim_invalid(x);
+    }
+    private static void dolong() throws Throwable {
+        long x = Long.MIN_VALUE;
+        long D = Long.MAX_VALUE / ((long) (N / 2)) | BITS;
+        for (int i = 0; i < N; i++, x += D)
+            long2prim(x);
+        long2prim_invalid(x);
+    }
+    private static void dofloat() throws Throwable {
+        float x = Float.MIN_VALUE;
+        float D = Float.MAX_VALUE / ((float) (N / 2));
+        for (int i = 0; i < N; i++, x += D)
+            float2prim(x);
+        float2prim_invalid(x);
+    }
+    private static void dodouble() throws Throwable {
+        double x = Double.MIN_VALUE;
+        double D = Double.MAX_VALUE / ((double) (N / 2));
+        for (int i = 0; i < N; i++, x += D)
+            double2prim(x);
+        double2prim_invalid(x);
+    }
+    private static void dovoid() throws Throwable {
+        for (int i = 0; i < N; i++) {
+            void2prim(i);
+        }
+        void2prim_invalid(0);
+        // do the other direction here also:
+        for (int i = 0; i < N; i++) {
+            prim2void(i);
+        }
+        prim2void_invalid(0);
+    }
+
+    private static void assertEquals(Object o, Object o2) {
+        if (!o.equals(o2))
+            throw new AssertionError("expected: " + o + ", found: " + o2);
+    }
+    private static void fail() {
+        throw new AssertionError();
+    }
+
+    private final static MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+    private static MethodHandle mh(Class ret, Class... args) {
+        try {
+            MethodType mt  = MethodType.methodType(ret, args);
+            Class lookupRet = (args.length == 0 ? void.class : args[0]);
+            MethodHandle mh = lookup.findStatic(CLASS, NAME, mt.changeReturnType(lookupRet));
+            if (DO_CASTS)
+                return MethodHandles.explicitCastArguments(mh, mt);
+            if (canDoAsType(mh.type(), mt))
+                return mh.asType(mt);
+            try {
+                mh.asType(mt);
+                throw new AssertionError("asType should not succeed: "+mh+" => "+mt);
+            } catch (WrongMethodTypeException ex) {
+                // this was a required WMTE
+                return mh.asType(mt.generic()).asType(mt);
+            }
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    private static final Class<?>[] NUMERIC_TYPE_WIDENING_ORDER = {
+        byte.class, short.class, int.class, long.class, float.class, double.class
+    };
+    private static boolean canDoAsType(Class<?> src, Class<?> dst) {
+        if (src == dst)  return true;
+        if (dst == void.class)  return true;
+        if (!src.isPrimitive() || !dst.isPrimitive())  return true;
+        // primitive conversion works for asType only when it's widening
+        if (src == boolean.class || dst == boolean.class)  return false;
+        if (dst == char.class)  return false;
+        if (src == char.class)  src = int.class;  // can widen char to int
+        for (Class<?> ntype : NUMERIC_TYPE_WIDENING_ORDER) {
+            if (src == ntype)  return true;
+            if (dst == ntype)  return false;
+        }
+        throw new AssertionError("should not reach here: "+src+", "+dst);
+    }
+    private static boolean canDoAsType(MethodType mt0, MethodType mt1) {
+        Class<?> rt0 = mt0.returnType();
+        Class<?> rt1 = mt1.returnType();
+        if (!canDoAsType(rt0, rt1))  return false;
+        int argc = mt0.parameterCount();
+        if (argc != mt1.parameterCount())  return false;
+        for (int i = 0; i < argc; i++) {
+            if (!canDoAsType(mt1.parameterType(i), mt0.parameterType(i)))
+                return false;
+        }
+        return true;
+    }
+
+    private static MethodHandle mh_z(Class ret) { return mh(ret, boolean.class); }
+
+    private final static MethodHandle mh_zz = mh_z(boolean.class);
+    private final static MethodHandle mh_bz = mh_z(byte.class   );
+    private final static MethodHandle mh_cz = mh_z(char.class   );
+    private final static MethodHandle mh_sz = mh_z(short.class  );
+    private final static MethodHandle mh_iz = mh_z(int.class    );
+    private final static MethodHandle mh_jz = mh_z(long.class   );
+    private final static MethodHandle mh_fz = mh_z(float.class  );
+    private final static MethodHandle mh_dz = mh_z(double.class );
+
+    private static void boolean2prim(boolean x) throws Throwable {
+        int i = x ? 1 : 0;
+        assertEquals(          x, (boolean) mh_zz.invokeExact(x));  // boolean -> boolean
+        if (!DO_CASTS)  return;
+        assertEquals((byte)    i, (byte)    mh_bz.invokeExact(x));  // boolean -> byte
+        assertEquals((char)    i, (char)    mh_cz.invokeExact(x));  // boolean -> char
+        assertEquals((short)   i, (short)   mh_sz.invokeExact(x));  // boolean -> short
+        assertEquals((int)     i, (int)     mh_iz.invokeExact(x));  // boolean -> int
+        assertEquals((long)    i, (long)    mh_jz.invokeExact(x));  // boolean -> long
+        assertEquals((float)   i, (float)   mh_fz.invokeExact(x));  // boolean -> float
+        assertEquals((double)  i, (double)  mh_dz.invokeExact(x));  // boolean -> double
+    }
+    private static void boolean2prim_invalid(boolean x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { byte    y = (byte)    mh_bz.invokeExact(x); fail(); } catch (ClassCastException _) {}  // boolean -> byte
+        try { char    y = (char)    mh_cz.invokeExact(x); fail(); } catch (ClassCastException _) {}  // boolean -> char
+        try { short   y = (short)   mh_sz.invokeExact(x); fail(); } catch (ClassCastException _) {}  // boolean -> short
+        try { int     y = (int)     mh_iz.invokeExact(x); fail(); } catch (ClassCastException _) {}  // boolean -> int
+        try { long    y = (long)    mh_jz.invokeExact(x); fail(); } catch (ClassCastException _) {}  // boolean -> long
+        try { float   y = (float)   mh_fz.invokeExact(x); fail(); } catch (ClassCastException _) {}  // boolean -> float
+        try { double  y = (double)  mh_dz.invokeExact(x); fail(); } catch (ClassCastException _) {}  // boolean -> double
+    }
+
+    private static MethodHandle mh_b(Class ret) { return mh(ret, byte.class); }
+
+    private final static MethodHandle mh_zb = mh_b(boolean.class);
+    private final static MethodHandle mh_bb = mh_b(byte.class   );
+    private final static MethodHandle mh_cb = mh_b(char.class   );
+    private final static MethodHandle mh_sb = mh_b(short.class  );
+    private final static MethodHandle mh_ib = mh_b(int.class    );
+    private final static MethodHandle mh_jb = mh_b(long.class   );
+    private final static MethodHandle mh_fb = mh_b(float.class  );
+    private final static MethodHandle mh_db = mh_b(double.class );
+
+    private static void byte2prim(byte x) throws Throwable {
+        assertEquals((byte)    x, (byte)    mh_bb.invokeExact(x));  // byte -> byte
+        assertEquals((short)   x, (short)   mh_sb.invokeExact(x));  // byte -> short
+        assertEquals((int)     x, (int)     mh_ib.invokeExact(x));  // byte -> int
+        assertEquals((long)    x, (long)    mh_jb.invokeExact(x));  // byte -> long
+        assertEquals((float)   x, (float)   mh_fb.invokeExact(x));  // byte -> float
+        assertEquals((double)  x, (double)  mh_db.invokeExact(x));  // byte -> double
+        if (!DO_CASTS)  return;
+        boolean z = ((x & 1) != 0);
+        assertEquals((char)    x, (char)    mh_cb.invokeExact(x));  // byte -> char
+        assertEquals((boolean) z, (boolean) mh_zb.invokeExact(x));  // byte -> boolean
+    }
+    private static void byte2prim_invalid(byte x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { char    y = (char)    mh_cb.invokeExact(x); fail(); } catch (ClassCastException _) {}  // byte -> char
+        try { boolean y = (boolean) mh_zb.invokeExact(x); fail(); } catch (ClassCastException _) {}  // byte -> boolean
+    }
+
+    private static MethodHandle mh_c(Class ret) { return mh(ret, char.class); }
+
+    private final static MethodHandle mh_zc = mh_c(boolean.class);
+    private final static MethodHandle mh_bc = mh_c(byte.class   );
+    private final static MethodHandle mh_cc = mh_c(char.class   );
+    private final static MethodHandle mh_sc = mh_c(short.class  );
+    private final static MethodHandle mh_ic = mh_c(int.class    );
+    private final static MethodHandle mh_jc = mh_c(long.class   );
+    private final static MethodHandle mh_fc = mh_c(float.class  );
+    private final static MethodHandle mh_dc = mh_c(double.class );
+
+    private static void char2prim(char x) throws Throwable {
+        assertEquals((char)    x, (char)    mh_cc.invokeExact(x));  // char -> char
+        assertEquals((int)     x, (int)     mh_ic.invokeExact(x));  // char -> int
+        assertEquals((long)    x, (long)    mh_jc.invokeExact(x));  // char -> long
+        assertEquals((float)   x, (float)   mh_fc.invokeExact(x));  // char -> float
+        assertEquals((double)  x, (double)  mh_dc.invokeExact(x));  // char -> double
+        if (!DO_CASTS)  return;
+        boolean z = ((x & 1) != 0);
+        assertEquals((boolean) z, (boolean) mh_zc.invokeExact(x));  // char -> boolean
+        assertEquals((byte)    x, (byte)    mh_bc.invokeExact(x));  // char -> byte
+        assertEquals((short)   x, (short)   mh_sc.invokeExact(x));  // char -> short
+    }
+    private static void char2prim_invalid(char x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { boolean y = (boolean) mh_zc.invokeExact(x); fail(); } catch (ClassCastException _) {}  // char -> boolean
+        try { byte    y = (byte)    mh_bc.invokeExact(x); fail(); } catch (ClassCastException _) {}  // char -> byte
+        try { short   y = (short)   mh_sc.invokeExact(x); fail(); } catch (ClassCastException _) {}  // char -> short
+    }
+
+    private static MethodHandle mh_s(Class ret) { return mh(ret, short.class); }
+
+    private final static MethodHandle mh_zs = mh_s(boolean.class);
+    private final static MethodHandle mh_bs = mh_s(byte.class   );
+    private final static MethodHandle mh_cs = mh_s(char.class   );
+    private final static MethodHandle mh_ss = mh_s(short.class  );
+    private final static MethodHandle mh_is = mh_s(int.class    );
+    private final static MethodHandle mh_js = mh_s(long.class   );
+    private final static MethodHandle mh_fs = mh_s(float.class  );
+    private final static MethodHandle mh_ds = mh_s(double.class );
+
+    private static void short2prim(short x) throws Throwable {
+        assertEquals((short)   x, (short)   mh_ss.invokeExact(x));  // short -> short
+        assertEquals((int)     x, (int)     mh_is.invokeExact(x));  // short -> int
+        assertEquals((long)    x, (long)    mh_js.invokeExact(x));  // short -> long
+        assertEquals((float)   x, (float)   mh_fs.invokeExact(x));  // short -> float
+        assertEquals((double)  x, (double)  mh_ds.invokeExact(x));  // short -> double
+        if (!DO_CASTS)  return;
+        boolean z = ((x & 1) != 0);
+        assertEquals((boolean) z, (boolean) mh_zs.invokeExact(x));  // short -> boolean
+        assertEquals((byte)    x, (byte)    mh_bs.invokeExact(x));  // short -> byte
+        assertEquals((char)    x, (char)    mh_cs.invokeExact(x));  // short -> char
+    }
+    private static void short2prim_invalid(short x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { boolean y = (boolean) mh_zs.invokeExact(x); fail(); } catch (ClassCastException _) {}  // short -> boolean
+        try { byte    y = (byte)    mh_bs.invokeExact(x); fail(); } catch (ClassCastException _) {}  // short -> byte
+        try { char    y = (char)    mh_cs.invokeExact(x); fail(); } catch (ClassCastException _) {}  // short -> char
+    }
+
+    private static MethodHandle mh_i(Class ret) { return mh(ret, int.class); }
+
+    private final static MethodHandle mh_zi = mh_i(boolean.class);
+    private final static MethodHandle mh_bi = mh_i(byte.class   );
+    private final static MethodHandle mh_ci = mh_i(char.class   );
+    private final static MethodHandle mh_si = mh_i(short.class  );
+    private final static MethodHandle mh_ii = mh_i(int.class    );
+    private final static MethodHandle mh_ji = mh_i(long.class   );
+    private final static MethodHandle mh_fi = mh_i(float.class  );
+    private final static MethodHandle mh_di = mh_i(double.class );
+
+    private static void int2prim(int x) throws Throwable {
+        assertEquals((int)     x, (int)     mh_ii.invokeExact(x));  // int -> int
+        assertEquals((long)    x, (long)    mh_ji.invokeExact(x));  // int -> long
+        assertEquals((float)   x, (float)   mh_fi.invokeExact(x));  // int -> float
+        assertEquals((double)  x, (double)  mh_di.invokeExact(x));  // int -> double
+        if (!DO_CASTS)  return;
+        boolean z = ((x & 1) != 0);
+        assertEquals((boolean) z, (boolean) mh_zi.invokeExact(x));  // int -> boolean
+        assertEquals((byte)    x, (byte)    mh_bi.invokeExact(x));  // int -> byte
+        assertEquals((char)    x, (char)    mh_ci.invokeExact(x));  // int -> char
+        assertEquals((short)   x, (short)   mh_si.invokeExact(x));  // int -> short
+    }
+    private static void int2prim_invalid(int x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { boolean y = (boolean) mh_zi.invokeExact(x); fail(); } catch (ClassCastException _) {}  // int -> boolean
+        try { byte    y = (byte)    mh_bi.invokeExact(x); fail(); } catch (ClassCastException _) {}  // int -> byte
+        try { char    y = (char)    mh_ci.invokeExact(x); fail(); } catch (ClassCastException _) {}  // int -> char
+        try { short   y = (short)   mh_si.invokeExact(x); fail(); } catch (ClassCastException _) {}  // int -> short
+    }
+
+    private static MethodHandle mh_j(Class ret) { return mh(ret, long.class); }
+
+    private final static MethodHandle mh_zj = mh_j(boolean.class);
+    private final static MethodHandle mh_bj = mh_j(byte.class   );
+    private final static MethodHandle mh_cj = mh_j(char.class   );
+    private final static MethodHandle mh_sj = mh_j(short.class  );
+    private final static MethodHandle mh_ij = mh_j(int.class    );
+    private final static MethodHandle mh_jj = mh_j(long.class   );
+    private final static MethodHandle mh_fj = mh_j(float.class  );
+    private final static MethodHandle mh_dj = mh_j(double.class );
+
+    private static void long2prim(long x) throws Throwable {
+        assertEquals((long)   x, (long)    mh_jj.invokeExact(x));  // long -> long
+        assertEquals((float)  x, (float)   mh_fj.invokeExact(x));  // long -> float
+        assertEquals((double) x, (double)  mh_dj.invokeExact(x));  // long -> double
+        if (!DO_CASTS)  return;
+        boolean z = ((x & 1) != 0);
+        assertEquals((boolean)z, (boolean) mh_zj.invokeExact(x));  // long -> boolean
+        assertEquals((byte)   x, (byte)    mh_bj.invokeExact(x));  // long -> byte
+        assertEquals((char)   x, (char)    mh_cj.invokeExact(x));  // long -> char
+        assertEquals((short)  x, (short)   mh_sj.invokeExact(x));  // long -> short
+        assertEquals((int)    x, (int)     mh_ij.invokeExact(x));  // long -> int
+    }
+    private static void long2prim_invalid(long x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { boolean y = (boolean) mh_zj.invokeExact(x); fail(); } catch (ClassCastException _) {}  // long -> boolean
+        try { byte    y = (byte)    mh_bj.invokeExact(x); fail(); } catch (ClassCastException _) {}  // long -> byte
+        try { char    y = (char)    mh_cj.invokeExact(x); fail(); } catch (ClassCastException _) {}  // long -> char
+        try { short   y = (short)   mh_sj.invokeExact(x); fail(); } catch (ClassCastException _) {}  // long -> short
+        try { int     y = (int)     mh_ij.invokeExact(x); fail(); } catch (ClassCastException _) {}  // long -> int
+    }
+
+    private static MethodHandle mh_f(Class ret) { return mh(ret, float.class); }
+
+    private final static MethodHandle mh_zf = mh_f(boolean.class);
+    private final static MethodHandle mh_bf = mh_f(byte.class   );
+    private final static MethodHandle mh_cf = mh_f(char.class   );
+    private final static MethodHandle mh_sf = mh_f(short.class  );
+    private final static MethodHandle mh_if = mh_f(int.class    );
+    private final static MethodHandle mh_jf = mh_f(long.class   );
+    private final static MethodHandle mh_ff = mh_f(float.class  );
+    private final static MethodHandle mh_df = mh_f(double.class );
+
+    private static void float2prim(float x) throws Throwable {
+        assertEquals((float)   x, (float)   mh_ff.invokeExact(x));  // float -> float
+        assertEquals((double)  x, (double)  mh_df.invokeExact(x));  // float -> double
+        if (!DO_CASTS)  return;
+        boolean z = (((byte) x & 1) != 0);
+        assertEquals((boolean) z, (boolean) mh_zf.invokeExact(x));  // float -> boolean
+        assertEquals((byte)    x, (byte)    mh_bf.invokeExact(x));  // float -> byte
+        assertEquals((char)    x, (char)    mh_cf.invokeExact(x));  // float -> char
+        assertEquals((short)   x, (short)   mh_sf.invokeExact(x));  // float -> short
+        assertEquals((int)     x, (int)     mh_if.invokeExact(x));  // float -> int
+        assertEquals((long)    x, (long)    mh_jf.invokeExact(x));  // float -> long
+    }
+    private static void float2prim_invalid(float x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { boolean y = (boolean) mh_zf.invokeExact(x); fail(); } catch (ClassCastException _) {}  // float -> boolean
+        try { byte    y = (byte)    mh_bf.invokeExact(x); fail(); } catch (ClassCastException _) {}  // float -> byte
+        try { char    y = (char)    mh_cf.invokeExact(x); fail(); } catch (ClassCastException _) {}  // float -> char
+        try { short   y = (short)   mh_sf.invokeExact(x); fail(); } catch (ClassCastException _) {}  // float -> short
+        try { int     y = (int)     mh_if.invokeExact(x); fail(); } catch (ClassCastException _) {}  // float -> int
+        try { long    y = (long)    mh_jf.invokeExact(x); fail(); } catch (ClassCastException _) {}  // float -> long
+    }
+
+    private static MethodHandle mh_d(Class ret) { return mh(ret, double.class); }
+
+    private final static MethodHandle mh_zd = mh_d(boolean.class);
+    private final static MethodHandle mh_bd = mh_d(byte.class   );
+    private final static MethodHandle mh_cd = mh_d(char.class   );
+    private final static MethodHandle mh_sd = mh_d(short.class  );
+    private final static MethodHandle mh_id = mh_d(int.class    );
+    private final static MethodHandle mh_jd = mh_d(long.class   );
+    private final static MethodHandle mh_fd = mh_d(float.class  );
+    private final static MethodHandle mh_dd = mh_d(double.class );
+
+    private static void double2prim(double x) throws Throwable {
+        assertEquals((double) x, (double)  mh_dd.invokeExact(x));  // double -> double
+        if (!DO_CASTS)  return;
+        boolean z = (((byte) x & 1) != 0);
+        assertEquals((boolean) z, (boolean) mh_zd.invokeExact(x));  // double -> boolean
+        assertEquals((byte)    x, (byte)    mh_bd.invokeExact(x));  // double -> byte
+        assertEquals((char)    x, (char)    mh_cd.invokeExact(x));  // double -> char
+        assertEquals((short)   x, (short)   mh_sd.invokeExact(x));  // double -> short
+        assertEquals((int)     x, (int)     mh_id.invokeExact(x));  // double -> int
+        assertEquals((long)    x, (long)    mh_jd.invokeExact(x));  // double -> long
+        assertEquals((float)   x, (float)   mh_fd.invokeExact(x));  // double -> float
+    }
+    private static void double2prim_invalid(double x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { boolean y = (boolean) mh_zd.invokeExact(x); fail(); } catch (ClassCastException _) {}  // double -> boolean
+        try { byte    y = (byte)    mh_bd.invokeExact(x); fail(); } catch (ClassCastException _) {}  // double -> byte
+        try { char    y = (char)    mh_cd.invokeExact(x); fail(); } catch (ClassCastException _) {}  // double -> char
+        try { short   y = (short)   mh_sd.invokeExact(x); fail(); } catch (ClassCastException _) {}  // double -> short
+        try { int     y = (int)     mh_id.invokeExact(x); fail(); } catch (ClassCastException _) {}  // double -> int
+        try { long    y = (long)    mh_jd.invokeExact(x); fail(); } catch (ClassCastException _) {}  // double -> long
+        try { float   y = (float)   mh_fd.invokeExact(x); fail(); } catch (ClassCastException _) {}  // double -> float
+    }
+
+    private final static MethodHandle mh_zv = mh(boolean.class);
+    private final static MethodHandle mh_bv = mh(byte.class   );
+    private final static MethodHandle mh_cv = mh(char.class   );
+    private final static MethodHandle mh_sv = mh(short.class  );
+    private final static MethodHandle mh_iv = mh(int.class    );
+    private final static MethodHandle mh_jv = mh(long.class   );
+    private final static MethodHandle mh_fv = mh(float.class  );
+    private final static MethodHandle mh_dv = mh(double.class );
+
+    private static void void2prim(int i) throws Throwable {
+        if (!DO_CASTS)  return;
+        assertEquals(        false, (boolean) mh_zv.invokeExact());  // void -> boolean
+        assertEquals((byte)  0,     (byte)    mh_bv.invokeExact());  // void -> byte
+        assertEquals((char)  0,     (char)    mh_cv.invokeExact());  // void -> char
+        assertEquals((short) 0,     (short)   mh_sv.invokeExact());  // void -> short
+        assertEquals(        0,     (int)     mh_iv.invokeExact());  // void -> int
+        assertEquals(        0L,    (long)    mh_jv.invokeExact());  // void -> long
+        assertEquals(        0.0f,  (float)   mh_fv.invokeExact());  // void -> float
+        assertEquals(        0.0d,  (double)  mh_dv.invokeExact());  // void -> double
+    }
+
+    private static void void2prim_invalid(double x) throws Throwable {
+        if (DO_CASTS)  return;
+        try { assertEquals(        false, (boolean) mh_zv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> boolean
+        try { assertEquals((byte)  0,     (byte)    mh_bv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> byte
+        try { assertEquals((char)  0,     (char)    mh_cv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> char
+        try { assertEquals((short) 0,     (short)   mh_sv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> short
+        try { assertEquals(        0,     (int)     mh_iv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> int
+        try { assertEquals(        0L,    (long)    mh_jv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> long
+        try { assertEquals(        0.0f,  (float)   mh_fv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> float
+        try { assertEquals(        0.0d,  (double)  mh_dv.invokeExact()); fail(); } catch (NullPointerException _) {}  // void -> double
+    }
+
+    private static MethodHandle mh_v(Class arg) { return mh(void.class, arg); }
+
+    private final static MethodHandle mh_vz = mh_v(boolean.class);
+    private final static MethodHandle mh_vb = mh_v(byte.class   );
+    private final static MethodHandle mh_vc = mh_v(char.class   );
+    private final static MethodHandle mh_vs = mh_v(short.class  );
+    private final static MethodHandle mh_vi = mh_v(int.class    );
+    private final static MethodHandle mh_vj = mh_v(long.class   );
+    private final static MethodHandle mh_vf = mh_v(float.class  );
+    private final static MethodHandle mh_vd = mh_v(double.class );
+
+    private static void prim2void(int x) throws Throwable {
+        boolean z = ((x & 1) != 0);
+        mh_vz.invokeExact(         z);  // boolean -> void
+        mh_vb.invokeExact((byte)   x);  // byte    -> void
+        mh_vc.invokeExact((char)   x);  // char    -> void
+        mh_vs.invokeExact((short)  x);  // short   -> void
+        mh_vi.invokeExact((int)    x);  // int     -> void
+        mh_vj.invokeExact((long)   x);  // long    -> void
+        mh_vf.invokeExact((float)  x);  // float   -> void
+        mh_vd.invokeExact((double) x);  // double  -> void
+    }
+
+    private static void prim2void_invalid(int x) throws Throwable {
+        // no cases
+    }
+
+    private static boolean identity(boolean v) { return v; }
+    private static byte    identity(byte    v) { return v; }
+    private static char    identity(char    v) { return v; }
+    private static short   identity(short   v) { return v; }
+    private static int     identity(int     v) { return v; }
+    private static long    identity(long    v) { return v; }
+    private static float   identity(float   v) { return v; }
+    private static double  identity(double  v) { return v; }
+    private static void    identity() {}
+}
--- a/jdk/test/java/lang/invoke/InvokeGenericTest.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/lang/invoke/InvokeGenericTest.java	Wed May 18 13:19:32 2011 +0200
@@ -24,7 +24,7 @@
  */
 
 /* @test
- * @summary unit tests for java.lang.invoke.MethodHandle.invokeGeneric
+ * @summary unit tests for java.lang.invoke.MethodHandle.invoke
  * @compile -target 7 InvokeGenericTest.java
  * @run junit/othervm test.java.lang.invoke.InvokeGenericTest
  */
@@ -53,6 +53,10 @@
         if (vstr != null)  verbosity = Integer.parseInt(vstr);
     }
 
+    public static void main(String... av) throws Throwable {
+        new InvokeGenericTest().testFirst();
+    }
+
     @Test
     public void testFirst() throws Throwable {
         verbosity += 9; try {
@@ -103,7 +107,7 @@
     void startTest(String name) {
         if (testName != null)  printCounts();
         if (verbosity >= 1)
-            System.out.println(name);
+            System.out.println("["+name+"]");
         posTests = negTests = 0;
         testName = name;
     }
@@ -350,6 +354,30 @@
         String[] args = { "one", "two" };
         MethodHandle mh = callable(Object.class, String.class);
         Object res; List resl;
+        res = resl = (List) mh.invoke((String)args[0], (Object)args[1]);
+        //System.out.println(res);
+        assertEquals(Arrays.asList(args), res);
+    }
+
+    @Test
+    public void testSimplePrims() throws Throwable {
+        startTest("testSimplePrims");
+        countTest();
+        int[] args = { 1, 2 };
+        MethodHandle mh = callable(Object.class, Object.class);
+        Object res; List resl;
+        res = resl = (List) mh.invoke(args[0], args[1]);
+        //System.out.println(res);
+        assertEquals(Arrays.toString(args), res.toString());
+    }
+
+    @Test
+    public void testAlternateName() throws Throwable {
+        startTest("testAlternateName");
+        countTest();
+        String[] args = { "one", "two" };
+        MethodHandle mh = callable(Object.class, String.class);
+        Object res; List resl;
         res = resl = (List) mh.invokeGeneric((String)args[0], (Object)args[1]);
         //System.out.println(res);
         assertEquals(Arrays.asList(args), res);
@@ -388,24 +416,24 @@
         try {
             switch (args.length) {
             case 0:
-                junk = target.invokeGeneric(); break;
+                junk = target.invoke(); break;
             case 1:
-                junk = target.invokeGeneric(args[0]); break;
+                junk = target.invoke(args[0]); break;
             case 2:
-                junk = target.invokeGeneric(args[0], args[1]); break;
+                junk = target.invoke(args[0], args[1]); break;
             case 3:
-                junk = target.invokeGeneric(args[0], args[1], args[2]); break;
+                junk = target.invoke(args[0], args[1], args[2]); break;
             case 4:
-                junk = target.invokeGeneric(args[0], args[1], args[2], args[3]); break;
+                junk = target.invoke(args[0], args[1], args[2], args[3]); break;
             default:
                 junk = target.invokeWithArguments(args); break;
             }
         } catch (WrongMethodTypeException ex) {
             return;
         } catch (Exception ex) {
-            throw new RuntimeException("wrong exception calling "+target+target.type()+" on "+Arrays.asList(args)+" : "+ex);
+            throw new RuntimeException("wrong exception calling "+target+" on "+Arrays.asList(args), ex);
         }
-        throw new RuntimeException("bad success calling "+target+target.type()+" on "+Arrays.asList(args));
+        throw new RuntimeException("bad success calling "+target+" on "+Arrays.asList(args));
     }
 
     /** Make a list of all combinations of the given types, with the given arities.
@@ -451,7 +479,7 @@
         startTest("testReferenceConversions");
         toString_MH = LOOKUP.
             findVirtual(Object.class, "toString", MethodType.methodType(String.class));
-        String[] args = { "one", "two" };
+        Object[] args = { "one", "two" };
         for (MethodType type : allMethodTypes(2, Object.class, String.class, RandomInterface.class)) {
             testReferenceConversions(type, args);
         }
@@ -463,7 +491,7 @@
         MethodHandle tsdrop = MethodHandles.dropArguments(toString_MH, 1, type.parameterList());
         mh = MethodHandles.foldArguments(tsdrop, mh);
         mh = mh.asType(type);
-        Object res = mh.invokeGeneric((String)args[0], (Object)args[1]);
+        Object res = mh.invoke((String)args[0], (Object)args[1]);
         //System.out.println(res);
         assertEquals(Arrays.asList(args).toString(), res);
     }
@@ -473,10 +501,10 @@
     public void testBoxConversions() throws Throwable {
         startTest("testBoxConversions");
         countTest();
-        Integer[] args = { 1, 2 };
+        Object[] args = { 1, 2 };
         MethodHandle mh = callable(Object.class, int.class);
         Object res; List resl;
-        res = resl = (List) mh.invokeGeneric((int)args[0], (Object)args[1]);
+        res = resl = (List) mh.invoke((int)args[0], (Object)args[1]);
         //System.out.println(res);
         assertEquals(Arrays.asList(args), res);
     }
--- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java	Wed May 18 13:19:32 2011 +0200
@@ -170,8 +170,8 @@
 mt = MethodType.methodType(java.util.List.class, Object[].class);
 mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
 assert(mh.isVarargsCollector());
-x = mh.invokeGeneric("one", "two");
-// invokeGeneric(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
+x = mh.invoke("one", "two");
+// invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
 assert(x.equals(java.util.Arrays.asList("one","two")));
 // mt is (Object,Object,Object)Object
 mt = MethodType.genericMethodType(3);
@@ -199,12 +199,12 @@
 MethodHandle asList = publicLookup()
   .findStatic(Arrays.class, "asList", methodType(List.class, Object[].class))
   .asVarargsCollector(Object[].class);
-assertEquals("[]", asList.invokeGeneric().toString());
-assertEquals("[1]", asList.invokeGeneric(1).toString());
-assertEquals("[two, too]", asList.invokeGeneric("two", "too").toString());
+assertEquals("[]", asList.invoke().toString());
+assertEquals("[1]", asList.invoke(1).toString());
+assertEquals("[two, too]", asList.invoke("two", "too").toString());
 Object[] argv = { "three", "thee", "tee" };
-assertEquals("[three, thee, tee]", asList.invokeGeneric(argv).toString());
-List ls = (List) asList.invokeGeneric((Object)argv);
+assertEquals("[three, thee, tee]", asList.invoke(argv).toString());
+List ls = (List) asList.invoke((Object)argv);
 assertEquals(1, ls.size());
 assertEquals("[three, thee, tee]", Arrays.toString((Object[])ls.get(0)));
             }}
@@ -218,9 +218,9 @@
   .asVarargsCollector(Object[].class);
 MethodHandle mh = MethodHandles.exactInvoker(vamh.type()).bindTo(vamh);
 assert(vamh.type().equals(mh.type()));
-assertEquals("[1, 2, 3]", vamh.invokeGeneric(1,2,3).toString());
+assertEquals("[1, 2, 3]", vamh.invoke(1,2,3).toString());
 boolean failed = false;
-try { mh.invokeGeneric(1,2,3); }
+try { mh.invoke(1,2,3); }
 catch (WrongMethodTypeException ex) { failed = true; }
 assert(failed);
 {}
--- a/jdk/test/java/lang/invoke/MethodHandlesTest.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java	Wed May 18 13:19:32 2011 +0200
@@ -105,24 +105,6 @@
     public MethodHandlesTest() {
     }
 
-    @Before
-    public void checkImplementedPlatform() {
-        boolean platformOK = false;
-        Properties properties = System.getProperties();
-        String vers = properties.getProperty("java.vm.version");
-        String name = properties.getProperty("java.vm.name");
-        String arch = properties.getProperty("os.arch");
-        if ((arch.equals("amd64") || arch.equals("i386") || arch.equals("x86") ||
-             arch.equals("sparc") || arch.equals("sparcv9")) &&
-            (name.contains("Client") || name.contains("Server"))
-            ) {
-            platformOK = true;
-        } else {
-            System.err.println("Skipping tests for unsupported platform: "+Arrays.asList(vers, name, arch));
-        }
-        assumeTrue(platformOK);
-    }
-
     String testName;
     static int allPosTests, allNegTests;
     int posTests, negTests;
@@ -331,6 +313,9 @@
     static MethodHandle varargsArray(int arity) {
         return ValueConversions.varargsArray(arity);
     }
+    static MethodHandle varargsArray(Class<?> arrayType, int arity) {
+        return ValueConversions.varargsArray(arrayType, arity);
+    }
     /** Variation of varargsList, but with the given rtype. */
     static MethodHandle varargsList(int arity, Class<?> rtype) {
         MethodHandle list = varargsList(arity);
@@ -865,7 +850,7 @@
                     Class<?> type = (Class<?>) t[1];
                     Object value;
                     Field field;
-                    try {
+                        try {
                         field = HasFields.class.getDeclaredField(name);
                     } catch (Exception ex) {
                         throw new InternalError("no field HasFields."+name);
@@ -1144,16 +1129,9 @@
                 : MethodHandles.arrayElementSetter(arrayType);
         assertSame(mh.type(), expType);
         if (elemType != int.class && elemType != boolean.class) {
-            MethodType gtype;
-            if (true) { // FIXME: remove this path (and remove <void> below in the mh.invokes)
-                gtype = mh.type().changeParameterType(0, Object.class);
-                if (testSetter)
-                    gtype = gtype.changeParameterType(2, Object.class);
-                else
-                    gtype = gtype.changeReturnType(Object.class);
-            } else
-                // FIXME: This simpler path hits a bug in convertArguments => ToGeneric
-                gtype = mh.type().generic().changeParameterType(1, int.class);
+            // FIXME: change Integer.class and (Integer) below to int.class and (int) below.
+            MethodType gtype = mh.type().generic().changeParameterType(1, Integer.class);
+            if (testSetter)  gtype = gtype.changeReturnType(void.class);
             mh = MethodHandles.convertArguments(mh, gtype);
         }
         Object sawValue, expValue;
@@ -1169,7 +1147,7 @@
                 else if (elemType == boolean.class)
                     mh.invokeExact((boolean[]) array, i, (boolean)random);
                 else
-                    mh.invokeExact(array, i, random);
+                    mh.invokeExact(array, (Integer)i, random);
                 assertEquals(model, array2list(array));
             } else {
                 Array.set(array, i, random);
@@ -1189,7 +1167,7 @@
                 else if (elemType == boolean.class)
                     sawValue = (boolean) mh.invokeExact((boolean[]) array, i);
                 else
-                    sawValue = mh.invokeExact(array, i);
+                    sawValue = mh.invokeExact(array, (Integer)i);
                 assertEquals(sawValue, expValue);
                 assertEquals(model, array2list(array));
             }
@@ -1341,21 +1319,15 @@
             int numcases = 1;
             for (int outargs = 0; outargs <= max; outargs++) {
                 if (outargs - inargs >= MAX_ARG_INCREASE)  continue;
-                int[] reorder = new int[outargs];
                 int casStep = dilution + 1;
                 // Avoid some common factors:
                 while ((casStep > 2 && casStep % 2 == 0 && inargs % 2 == 0) ||
                        (casStep > 3 && casStep % 3 == 0 && inargs % 3 == 0))
                     casStep++;
-                for (int cas = 0; cas < numcases; cas += casStep) {
-                    for (int i = 0, c = cas; i < outargs; i++) {
-                        reorder[i] = c % inargs;
-                        c /= inargs;
-                    }
-                    testPermuteArguments(args, types, reorder);
-                }
+                testPermuteArguments(args, types, outargs, numcases, casStep);
                 numcases *= inargs;
                 if (dilution > 10 && outargs >= 4) {
+                    int[] reorder = new int[outargs];
                     // Do some special patterns, which we probably missed.
                     // Replication of a single argument or argument pair.
                     for (int i = 0; i < inargs; i++) {
@@ -1383,6 +1355,19 @@
         }
     }
 
+    public void testPermuteArguments(Object[] args, Class<?>[] types,
+                                     int outargs, int numcases, int casStep) throws Throwable {
+        int inargs = args.length;
+        int[] reorder = new int[outargs];
+        for (int cas = 0; cas < numcases; cas += casStep) {
+            for (int i = 0, c = cas; i < outargs; i++) {
+                reorder[i] = c % inargs;
+                c /= inargs;
+            }
+            testPermuteArguments(args, types, reorder);
+        }
+    }
+
     static int[] reverse(int[] reorder) {
         reorder = reorder.clone();
         for (int i = 0, imax = reorder.length / 2; i < imax; i++) {
@@ -1433,6 +1418,12 @@
         MethodHandle newTarget = MethodHandles.permuteArguments(target, inType, reorder);
         Object result = newTarget.invokeWithArguments(args);
         Object expected = Arrays.asList(permArgs);
+        if (!expected.equals(result)) {
+            System.out.println("*** failed permuteArguments "+Arrays.toString(reorder)+" types="+Arrays.asList(types));
+            System.out.println("in args:   "+Arrays.asList(args));
+            System.out.println("out args:  "+expected);
+            System.out.println("bad args:  "+result);
+        }
         assertEquals(expected, result);
     }
 
@@ -1456,26 +1447,27 @@
     }
     public void testSpreadArguments(Class<?> argType, int pos, int nargs) throws Throwable {
         countTest();
-        MethodHandle target = varargsArray(nargs);
-        MethodHandle target2 = changeArgTypes(target, argType);
+        Class<?> arrayType = java.lang.reflect.Array.newInstance(argType, 0).getClass();
+        MethodHandle target2 = varargsArray(arrayType, nargs);
+        MethodHandle target = target2.asType(target2.type().generic());
         if (verbosity >= 3)
             System.out.println("spread into "+target2+" ["+pos+".."+nargs+"]");
         Object[] args = randomArgs(target2.type().parameterArray());
         // make sure the target does what we think it does:
-        if (pos == 0 && nargs < 5) {
-            Object[] check = (Object[]) target.invokeWithArguments(args);
+        if (pos == 0 && nargs < 5 && !argType.isPrimitive()) {
+            Object[] check = (Object[]) (Object) target.invokeWithArguments(args);
             assertArrayEquals(args, check);
             switch (nargs) {
                 case 0:
-                    check = (Object[]) target.invokeExact();
+                    check = (Object[]) (Object) target.invokeExact();
                     assertArrayEquals(args, check);
                     break;
                 case 1:
-                    check = (Object[]) target.invokeExact(args[0]);
+                    check = (Object[]) (Object) target.invokeExact(args[0]);
                     assertArrayEquals(args, check);
                     break;
                 case 2:
-                    check = (Object[]) target.invokeExact(args[0], args[1]);
+                    check = (Object[]) (Object) target.invokeExact(args[0], args[1]);
                     assertArrayEquals(args, check);
                     break;
             }
@@ -1483,23 +1475,50 @@
         List<Class<?>> newParams = new ArrayList<Class<?>>(target2.type().parameterList());
         {   // modify newParams in place
             List<Class<?>> spreadParams = newParams.subList(pos, nargs);
-            spreadParams.clear(); spreadParams.add(Object[].class);
+            spreadParams.clear(); spreadParams.add(arrayType);
         }
-        MethodType newType = MethodType.methodType(Object.class, newParams);
-        MethodHandle result = target2.asSpreader(Object[].class, nargs-pos).asType(newType);
-        Object[] returnValue;
+        MethodType newType = MethodType.methodType(arrayType, newParams);
+        MethodHandle result = target2.asSpreader(arrayType, nargs-pos);
+        assert(result.type() == newType) : Arrays.asList(result, newType);
+        result = result.asType(newType.generic());
+        Object returnValue;
         if (pos == 0) {
-            // In the following line, the first cast implies
-            // normal Object return value for the MH call (Object[])->Object,
-            // while the second cast dynamically converts to an Object array.
-            // Such a double cast is typical of MH.invokeExact.
-            returnValue = (Object[]) (Object) result.invokeExact(args);
+            Object args2 = ValueConversions.changeArrayType(arrayType, Arrays.copyOfRange(args, pos, args.length));
+            returnValue = result.invokeExact(args2);
         } else {
             Object[] args1 = Arrays.copyOfRange(args, 0, pos+1);
-            args1[pos] = Arrays.copyOfRange(args, pos, args.length);
-            returnValue = (Object[]) result.invokeWithArguments(args1);
+            args1[pos] = ValueConversions.changeArrayType(arrayType, Arrays.copyOfRange(args, pos, args.length));
+            returnValue = result.invokeWithArguments(args1);
         }
-        assertArrayEquals(args, returnValue);
+        String argstr = Arrays.toString(args);
+        if (!argType.isPrimitive()) {
+            Object[] rv = (Object[]) returnValue;
+            String rvs = Arrays.toString(rv);
+            if (!Arrays.equals(args, rv)) {
+                System.out.println("method:   "+result);
+                System.out.println("expected: "+argstr);
+                System.out.println("returned: "+rvs);
+                assertArrayEquals(args, rv);
+            }
+        } else if (argType == int.class) {
+            String rvs = Arrays.toString((int[]) returnValue);
+            if (!argstr.equals(rvs)) {
+                System.out.println("method:   "+result);
+                System.out.println("expected: "+argstr);
+                System.out.println("returned: "+rvs);
+                assertEquals(argstr, rvs);
+            }
+        } else if (argType == long.class) {
+            String rvs = Arrays.toString((long[]) returnValue);
+            if (!argstr.equals(rvs)) {
+                System.out.println("method:   "+result);
+                System.out.println("expected: "+argstr);
+                System.out.println("returned: "+rvs);
+                assertEquals(argstr, rvs);
+            }
+        } else {
+            // cannot test...
+        }
     }
 
     @Test
@@ -1780,7 +1799,7 @@
         assertCalled("invokee", args);
         // generic invoker
         countTest();
-        inv = MethodHandles.genericInvoker(type);
+        inv = MethodHandles.invoker(type);
         if (nargs <= 3) {
             calledLog.clear();
             switch (nargs) {
@@ -2130,15 +2149,12 @@
             Object z = surprise.invokeExact(x);
             System.out.println("Failed to throw; got z="+z);
             assertTrue(false);
-        } catch (Exception ex) {
+        } catch (ClassCastException ex) {
             if (verbosity > 2)
                 System.out.println("caught "+ex);
             if (verbosity > 3)
                 ex.printStackTrace();
-            assertTrue(ex instanceof ClassCastException
-                    // FIXME: accept only one of the two for any given unit test
-                    || ex instanceof WrongMethodTypeException
-                    );
+            assertTrue(true);  // all is well
         }
     }
 
@@ -2328,6 +2344,34 @@
         // else need to spin bytecode or do something else fancy
         throw new UnsupportedOperationException("NYI: cannot form a varargs array of length "+nargs);
     }
+    public static MethodHandle varargsArray(Class<?> arrayType, int nargs) {
+        Class<?> elemType = arrayType.getComponentType();
+        MethodType vaType = MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType));
+        MethodHandle mh = varargsArray(nargs);
+        if (arrayType != Object[].class)
+            mh = MethodHandles.filterReturnValue(mh, CHANGE_ARRAY_TYPE.bindTo(arrayType));
+        return mh.asType(vaType);
+    }
+    static Object changeArrayType(Class<?> arrayType, Object[] a) {
+        Class<?> elemType = arrayType.getComponentType();
+        if (!elemType.isPrimitive())
+            return Arrays.copyOf(a, a.length, arrayType.asSubclass(Object[].class));
+        Object b = java.lang.reflect.Array.newInstance(elemType, a.length);
+        for (int i = 0; i < a.length; i++)
+            java.lang.reflect.Array.set(b, i, a[i]);
+        return b;
+    }
+    private static final MethodHandle CHANGE_ARRAY_TYPE;
+    static {
+        try {
+            CHANGE_ARRAY_TYPE = IMPL_LOOKUP.findStatic(ValueConversions.class, "changeArrayType",
+                                                       MethodType.methodType(Object.class, Class.class, Object[].class));
+        } catch (NoSuchMethodException | IllegalAccessException ex) {
+            Error err = new InternalError("uncaught exception");
+            err.initCause(ex);
+            throw err;
+        }
+    }
 
     private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
     private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/RicochetTest.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 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.
+ */
+
+/* @test
+ * @summary unit tests for recursive method handles
+ * @run junit/othervm -DRicochetTest.MAX_ARITY=255 test.java.lang.invoke.RicochetTest
+ */
+
+package test.java.lang.invoke;
+
+import java.lang.invoke.*;
+import java.util.*;
+import org.junit.*;
+import static java.lang.invoke.MethodType.*;
+import static java.lang.invoke.MethodHandles.*;
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+
+/**
+ *
+ * @author jrose
+ */
+public class RicochetTest {
+    private static final Class CLASS = RicochetTest.class;
+    private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
+
+    public static void main(String... av) throws Throwable {
+        RicochetTest test = new RicochetTest();
+        if (av.length > 0)  test.testOnly = Arrays.asList(av).toString();
+        if (REPEAT == 1 || test.testOnly != null) {
+            test.testAll();
+            if (test.testOnlyTests == null)  throw new RuntimeException("no matching test: "+test.testOnly);
+        } else if (REPEAT == 0) {
+            org.junit.runner.JUnitCore.runClasses(RicochetTest.class);
+        } else {
+            verbose(1, "REPEAT="+REPEAT);
+            for (int i = 0; i < REPEAT; i++) {
+                test.testRepetition = (i+1);
+                verbose(0, "[#"+test.testRepetition+"]");
+                test.testAll();
+            }
+        }
+    }
+    int testRepetition;
+
+    public void testAll() throws Throwable {
+        testNull();
+        testBoxInteger();
+        testFilterReturnValue();
+        testFilterObject();
+        testBoxLong();
+        testFilterInteger();
+        testIntSpreads();
+        testByteSpreads();
+        testLongSpreads();
+        testIntCollects();
+        testReturns();
+    }
+
+    @Test
+    public void testNull() throws Throwable {
+        if (testRepetition > (1+REPEAT/100))  return;  // trivial test
+        if (!startTest("testNull"))  return;
+        assertEquals(opI(37), opI.invokeWithArguments(37));
+        assertEqualFunction(opI, opI);
+    }
+
+    @Test
+    public void testBoxInteger() throws Throwable {
+        if (!startTest("testBoxInteger"))  return;
+        assertEqualFunction(opI, opI.asType(opL_I.type()).asType(opI.type()));
+    }
+
+    @Test
+    public void testFilterReturnValue() throws Throwable {
+        if (!startTest("testFilterReturnValue"))  return;
+        int[] ints = { 12, 23, 34, 45, 56, 67, 78, 89 };
+        Object res = list8ints.invokeExact(ints[0], ints[1], ints[2], ints[3], ints[4], ints[5], ints[6], ints[7]);
+        assertEquals(Arrays.toString(ints), res.toString());
+        MethodHandle idreturn = filterReturnValue(list8ints, identity(Object.class));
+        res = idreturn.invokeExact(ints[0], ints[1], ints[2], ints[3], ints[4], ints[5], ints[6], ints[7]);
+        assertEquals(Arrays.toString(ints), res.toString());
+        MethodHandle add0 = addL.bindTo(0);
+        assertEqualFunction(filterReturnValue(opL2, add0), opL2);
+    }
+
+    @Test
+    public void testFilterObject() throws Throwable {
+        if (!startTest("testFilterObject"))  return;
+        MethodHandle add0 = addL.bindTo(0);
+        assertEqualFunction(sequence(opL2, add0), opL2);
+        int bump13 = -13;  // value near 20 works as long as test values are near [-80..80]
+        MethodHandle add13   = addL.bindTo(bump13);
+        MethodHandle add13_0 = addL.bindTo(opI2(bump13, 0));
+        MethodHandle add13_1 = addL.bindTo(opI2(0, bump13));
+        assertEqualFunction(sequence(opL2, add13_0),
+                            filterArguments(opL2, 0, add13));
+        assertEqualFunction(sequence(opL2, add13_1),
+                            filterArguments(opL2, 1, add13));
+        System.out.println("[testFilterObject done]");
+    }
+
+    @Test
+    public void testBoxLong() throws Throwable {
+        if (!startTest("testBoxLong"))  return;
+        assertEqualFunction(opJ, opJ.asType(opL_J.type()).asType(opJ.type()));
+    }
+
+    @Test
+    public void testFilterInteger() throws Throwable {
+        if (!startTest("testFilterInteger"))  return;
+        assertEqualFunction(opI, sequence(convI_L, opL_I));
+    }
+
+    @Test
+    public void testIntSpreads() throws Throwable {
+        if (!startTest("testIntSpreads"))  return;
+        MethodHandle id = identity(int[].class);
+        final int MAX = MAX_ARITY-2;  // 253+1 would cause parameter overflow with 'this' added
+        for (int nargs = 0; nargs <= MAX; nargs++) {
+            if (nargs > 30 && nargs < MAX-20)  nargs += 10;
+            int[] args = new int[nargs];
+            for (int j = 0; j < args.length; j++)  args[j] = (int)(j + 11);
+            //System.out.println("testIntSpreads "+Arrays.toString(args));
+            int[] args1 = (int[]) id.invokeExact(args);
+            assertArrayEquals(args, args1);
+            MethodHandle coll = id.asCollector(int[].class, nargs);
+            int[] args2 = args;
+            switch (nargs) {
+                case 0:  args2 = (int[]) coll.invokeExact(); break;
+                case 1:  args2 = (int[]) coll.invokeExact(args[0]); break;
+                case 2:  args2 = (int[]) coll.invokeExact(args[0], args[1]); break;
+                case 3:  args2 = (int[]) coll.invokeExact(args[0], args[1], args[2]); break;
+                case 4:  args2 = (int[]) coll.invokeExact(args[0], args[1], args[2], args[3]); break;
+                case 5:  args2 = (int[]) coll.invokeExact(args[0], args[1], args[2], args[3], args[4]); break;
+            }
+            assertArrayEquals(args, args2);
+            MethodHandle mh = coll.asSpreader(int[].class, nargs);
+            int[] args3 = (int[]) mh.invokeExact(args);
+            assertArrayEquals(args, args3);
+        }
+    }
+
+    @Test
+    public void testByteSpreads() throws Throwable {
+        if (!startTest("testByteSpreads"))  return;
+        MethodHandle id = identity(byte[].class);
+        final int MAX = MAX_ARITY-2;  // 253+1 would cause parameter overflow with 'this' added
+        for (int nargs = 0; nargs <= MAX; nargs++) {
+            if (nargs > 30 && nargs < MAX-20)  nargs += 10;
+            byte[] args = new byte[nargs];
+            for (int j = 0; j < args.length; j++)  args[j] = (byte)(j + 11);
+            //System.out.println("testByteSpreads "+Arrays.toString(args));
+            byte[] args1 = (byte[]) id.invokeExact(args);
+            assertArrayEquals(args, args1);
+            MethodHandle coll = id.asCollector(byte[].class, nargs);
+            byte[] args2 = args;
+            switch (nargs) {
+                case 0:  args2 = (byte[]) coll.invokeExact(); break;
+                case 1:  args2 = (byte[]) coll.invokeExact(args[0]); break;
+                case 2:  args2 = (byte[]) coll.invokeExact(args[0], args[1]); break;
+                case 3:  args2 = (byte[]) coll.invokeExact(args[0], args[1], args[2]); break;
+                case 4:  args2 = (byte[]) coll.invokeExact(args[0], args[1], args[2], args[3]); break;
+                case 5:  args2 = (byte[]) coll.invokeExact(args[0], args[1], args[2], args[3], args[4]); break;
+            }
+            assertArrayEquals(args, args2);
+            MethodHandle mh = coll.asSpreader(byte[].class, nargs);
+            byte[] args3 = (byte[]) mh.invokeExact(args);
+            assertArrayEquals(args, args3);
+        }
+    }
+
+    @Test
+    public void testLongSpreads() throws Throwable {
+        if (!startTest("testLongSpreads"))  return;
+        MethodHandle id = identity(long[].class);
+        final int MAX = (MAX_ARITY - 2) / 2;  // 253/2+1 would cause parameter overflow with 'this' added
+        for (int nargs = 0; nargs <= MAX; nargs++) {
+            if (nargs > 30 && nargs < MAX-20)  nargs += 10;
+            long[] args = new long[nargs];
+            for (int j = 0; j < args.length; j++)  args[j] = (long)(j + 11);
+            //System.out.println("testLongSpreads "+Arrays.toString(args));
+            long[] args1 = (long[]) id.invokeExact(args);
+            assertArrayEquals(args, args1);
+            MethodHandle coll = id.asCollector(long[].class, nargs);
+            long[] args2 = args;
+            switch (nargs) {
+                case 0:  args2 = (long[]) coll.invokeExact(); break;
+                case 1:  args2 = (long[]) coll.invokeExact(args[0]); break;
+                case 2:  args2 = (long[]) coll.invokeExact(args[0], args[1]); break;
+                case 3:  args2 = (long[]) coll.invokeExact(args[0], args[1], args[2]); break;
+                case 4:  args2 = (long[]) coll.invokeExact(args[0], args[1], args[2], args[3]); break;
+                case 5:  args2 = (long[]) coll.invokeExact(args[0], args[1], args[2], args[3], args[4]); break;
+            }
+            assertArrayEquals(args, args2);
+            MethodHandle mh = coll.asSpreader(long[].class, nargs);
+            long[] args3 = (long[]) mh.invokeExact(args);
+            assertArrayEquals(args, args3);
+        }
+    }
+
+    @Test
+    public void testIntCollects() throws Throwable {
+        if (!startTest("testIntCollects"))  return;
+        for (MethodHandle lister : INT_LISTERS) {
+            int outputs = lister.type().parameterCount();
+            for (int collects = 0; collects <= Math.min(outputs, INT_COLLECTORS.length-1); collects++) {
+                int inputs = outputs - 1 + collects;
+                if (inputs < 0)  continue;
+                for (int pos = 0; pos + collects <= inputs; pos++) {
+                    MethodHandle collector = INT_COLLECTORS[collects];
+                    int[] args = new int[inputs];
+                    int ap = 0, arg = 31;
+                    for (int i = 0; i < pos; i++)
+                        args[ap++] = arg++ + 0;
+                    for (int i = 0; i < collects; i++)
+                        args[ap++] = arg++ + 10;
+                    while (ap < args.length)
+                        args[ap++] = arg++ + 20;
+                    // calculate piecemeal:
+                    //System.out.println("testIntCollects "+Arrays.asList(lister, pos, collector)+" on "+Arrays.toString(args));
+                    int[] collargs = Arrays.copyOfRange(args, pos, pos+collects);
+                    int coll = (int) collector.asSpreader(int[].class, collargs.length).invokeExact(collargs);
+                    int[] listargs = Arrays.copyOfRange(args, 0, outputs);
+                    System.arraycopy(args, pos+collects, listargs, pos+1, outputs - (pos+1));
+                    listargs[pos] = coll;
+                    //System.out.println("  coll="+coll+" listargs="+Arrays.toString(listargs));
+                    Object expect = lister.asSpreader(int[].class, listargs.length).invokeExact(listargs);
+                    //System.out.println("  expect="+expect);
+
+                    // now use the combined MH, and test the output:
+                    MethodHandle mh = collectArguments(lister, pos, INT_COLLECTORS[collects]);
+                    if (mh == null)  continue;  // no infix collection, yet
+                    assert(mh.type().parameterCount() == inputs);
+                    Object observe = mh.asSpreader(int[].class, args.length).invokeExact(args);
+                    assertEquals(expect, observe);
+                }
+            }
+        }
+    }
+
+    private static MethodHandle collectArguments(MethodHandle lister, int pos, MethodHandle collector) {
+        int collects = collector.type().parameterCount();
+        int outputs = lister.type().parameterCount();
+        if (pos == outputs - 1)
+            return MethodHandles.filterArguments(lister, pos,
+                        collector.asSpreader(int[].class, collects))
+                            .asCollector(int[].class, collects);
+        //return MethodHandles.collectArguments(lister, pos, collector); //no such animal
+        return null;
+    }
+
+    private static final Class<?>[] RETURN_TYPES = {
+        Object.class, String.class, Integer.class,
+        int.class, long.class,
+        boolean.class, byte.class, char.class, short.class,
+        float.class, double.class,
+        void.class,
+    };
+
+    @Test
+    public void testReturns() throws Throwable {
+        if (!startTest("testReturns"))  return;
+        // fault injection:
+        int faultCount = 0;  // total of 1296 tests
+        faultCount = Integer.getInteger("testReturns.faultCount", 0);
+        for (Class<?> ret : RETURN_TYPES) {
+            // make a complicated identity function and pass something through it
+            System.out.println(ret.getSimpleName());
+            Class<?> vret = (ret == void.class) ? Void.class : ret;
+            MethodHandle id = // (vret)->ret
+                identity(vret).asType(methodType(ret, vret));
+            final int LENGTH = 4;
+            int[] index = {0};
+            Object vals = java.lang.reflect.Array.newInstance(vret, LENGTH);
+            MethodHandle indexGetter =  //()->int
+                insertArguments(arrayElementGetter(index.getClass()), 0, index, 0);
+            MethodHandle valSelector =  // (int)->vret
+                arrayElementGetter(vals.getClass()).bindTo(vals);
+            MethodHandle valGetter =  // ()->vret
+                foldArguments(valSelector, indexGetter);
+            if (ret != void.class) {
+                for (int i = 0; i < LENGTH; i++) {
+                    Object val = (i + 50);
+                    if (ret == boolean.class)  val = (i % 3 == 0);
+                    if (ret == String.class)   val = "#"+i;
+                    if (ret == char.class)     val = (char)('a'+i);
+                    if (ret == byte.class)     val = (byte)~i;
+                    if (ret == short.class)    val = (short)(1<<i);
+                    java.lang.reflect.Array.set(vals, i, val);
+                }
+            }
+            for (int i = 0; i < LENGTH; i++) {
+                Object val = java.lang.reflect.Array.get(vals, i);
+                System.out.println(i+" => "+val);
+                index[0] = i;
+                if (--faultCount == 0)  index[0] ^= 1;
+                Object x = valGetter.invokeWithArguments();
+                assertEquals(val, x);
+                // make a return-filter call:  x = id(valGetter())
+                if (--faultCount == 0)  index[0] ^= 1;
+                x = filterReturnValue(valGetter, id).invokeWithArguments();
+                assertEquals(val, x);
+                // make a filter call:  x = id(*,valGetter(),*)
+                for (int len = 1; len <= 4; len++) {
+                    for (int pos = 0; pos < len; pos++) {
+                        MethodHandle proj = id;  // lambda(..., vret x,...){x}
+                        for (int j = 0; j < len; j++) {
+                            if (j == pos)  continue;
+                            proj = dropArguments(proj, j, Object.class);
+                        }
+                        assert(proj.type().parameterCount() == len);
+                        // proj: (Object*, pos: vret, Object*)->ret
+                        assertEquals(vret, proj.type().parameterType(pos));
+                        MethodHandle vgFilter = dropArguments(valGetter, 0, Object.class);
+                        if (--faultCount == 0)  index[0] ^= 1;
+                        x = filterArguments(proj, pos, vgFilter).invokeWithArguments(new Object[len]);
+                        assertEquals(val, x);
+                    }
+                }
+                // make a fold call:
+                for (int len = 0; len <= 4; len++) {
+                    for (int fold = 0; fold <= len; fold++) {
+                        MethodHandle proj = id;  // lambda(ret x, ...){x}
+                        if (ret == void.class)  proj = constant(Object.class, null);
+                        int arg0 = (ret == void.class ? 0 : 1);
+                        for (int j = 0; j < len; j++) {
+                            proj = dropArguments(proj, arg0, Object.class);
+                        }
+                        assert(proj.type().parameterCount() == arg0 + len);
+                        // proj: (Object*, pos: vret, Object*)->ret
+                        if (arg0 != 0)  assertEquals(vret, proj.type().parameterType(0));
+                        MethodHandle vgFilter = valGetter.asType(methodType(ret));
+                        for (int j = 0; j < fold; j++) {
+                            vgFilter = dropArguments(vgFilter, j, Object.class);
+                        }
+                        x = foldArguments(proj, vgFilter).invokeWithArguments(new Object[len]);
+                        if (--faultCount == 0)  index[0] ^= 1;
+                        assertEquals(val, x);
+                    }
+                }
+            }
+        }
+        //System.out.println("faultCount="+faultCount);
+    }
+
+    private static MethodHandle sequence(MethodHandle mh1, MethodHandle... mhs) {
+        MethodHandle res = mh1;
+        for (MethodHandle mh2 : mhs)
+            res = filterReturnValue(res, mh2);
+        return res;
+    }
+    private static void assertEqualFunction(MethodHandle x, MethodHandle y) throws Throwable {
+        assertEquals(x.type(), y.type()); //??
+        MethodType t = x.type();
+        if (t.parameterCount() == 0) {
+            assertEqualFunctionAt(null, x, y);
+            return;
+        }
+        Class<?> ptype = t.parameterType(0);
+        if (ptype == long.class || ptype == Long.class) {
+            for (long i = -10; i <= 10; i++) {
+                assertEqualFunctionAt(i, x, y);
+            }
+        } else {
+            for (int i = -10; i <= 10; i++) {
+                assertEqualFunctionAt(i, x, y);
+            }
+        }
+    }
+    private static void assertEqualFunctionAt(Object v, MethodHandle x, MethodHandle y) throws Throwable {
+        Object[] args = new Object[x.type().parameterCount()];
+        Arrays.fill(args, v);
+        Object xval = invokeWithCatch(x, args);
+        Object yval = invokeWithCatch(y, args);
+        String msg = "ok";
+        if (!Objects.equals(xval, yval)) {
+            msg = ("applying "+x+" & "+y+" to "+v);
+        }
+        assertEquals(msg, xval, yval);
+    }
+    private static Object invokeWithCatch(MethodHandle mh, Object... args) throws Throwable {
+        try {
+            return mh.invokeWithArguments(args);
+        } catch (Throwable ex) {
+            System.out.println("threw: "+mh+Arrays.asList(args));
+            ex.printStackTrace();
+            return ex;
+        }
+    }
+
+    private static final Lookup LOOKUP = lookup();
+    private static MethodHandle findStatic(String name,
+                                           Class<?> rtype,
+                                           Class<?>... ptypes) {
+        try {
+            return LOOKUP.findStatic(LOOKUP.lookupClass(), name, methodType(rtype, ptypes));
+        } catch (ReflectiveOperationException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    private static MethodHandle findStatic(String name,
+                                           Class<?> rtype,
+                                           List<?> ptypes) {
+        return findStatic(name, rtype, ptypes.toArray(new Class<?>[ptypes.size()]));
+    }
+    static int getProperty(String name, int dflt) {
+        String qual = LOOKUP.lookupClass().getName();
+        String prop = System.getProperty(qual+"."+name);
+        if (prop == null)  prop = System.getProperty(name);
+        if (prop == null)  return dflt;
+        return Integer.parseInt(prop);
+    }
+
+    private static int opI(int... xs) {
+        stress();
+        int base = 100;
+        int z = 0;
+        for (int x : xs) {
+            z = (z * base) + (x % base);
+        }
+        verbose("opI", xs.length, xs, z);
+        return z;
+    }
+    private static int opI2(int x, int y) { return opI(x, y); }  // x*100 + y%100
+    private static int opI3(int x, int y, int z) { return opI(x, y, z); }
+    private static int opI4(int w, int x, int y, int z) { return opI(w, x, y, z); }
+    private static int opI(int x) { return opI2(x, 37); }
+    private static Object opI_L(int x) { return (Object) opI(x); }
+    private static long opJ3(long x, long y, long z) { return (long) opI3((int)x, (int)y, (int)z); }
+    private static long opJ2(long x, long y) { return (long) opI2((int)x, (int)y); }
+    private static long opJ(long x) { return (long) opI((int)x); }
+    private static Object opL2(Object x, Object y) { return (Object) opI2((int)x, (int)y); }
+    private static Object opL(Object x) { return (Object) opI((int)x); }
+    private static int opL2_I(Object x, Object y) { return (int) opI2((int)x, (int)y); }
+    private static int opL_I(Object x) { return (int) opI((int)x); }
+    private static long opL_J(Object x) { return (long) opI((int)x); }
+    private static final MethodHandle opI, opI2, opI3, opI4, opI_L, opJ, opJ2, opJ3, opL2, opL, opL2_I, opL_I, opL_J;
+    static {
+        opI4 = findStatic("opI4", int.class, int.class, int.class, int.class, int.class);
+        opI3 = findStatic("opI3", int.class, int.class, int.class, int.class);
+        opI2 = findStatic("opI2", int.class, int.class, int.class);
+        opI = findStatic("opI", int.class, int.class);
+        opI_L = findStatic("opI_L", Object.class, int.class);
+        opJ = findStatic("opJ", long.class, long.class);
+        opJ2 = findStatic("opJ2", long.class, long.class, long.class);
+        opJ3 = findStatic("opJ3", long.class, long.class, long.class, long.class);
+        opL2 = findStatic("opL2", Object.class, Object.class, Object.class);
+        opL = findStatic("opL", Object.class, Object.class);
+        opL2_I = findStatic("opL2_I", int.class, Object.class, Object.class);
+        opL_I = findStatic("opL_I", int.class, Object.class);
+        opL_J = findStatic("opL_J", long.class, Object.class);
+    }
+    private static final MethodHandle[] INT_COLLECTORS = {
+        constant(int.class, 42), opI, opI2, opI3, opI4
+    };
+    private static final MethodHandle[] LONG_COLLECTORS = {
+        constant(long.class, 42), opJ, opJ2, opJ3
+    };
+
+    private static int addI(int x, int y) { stress(); return x+y; }
+    private static Object addL(Object x, Object y) { return addI((int)x, (int)y); }
+    private static final MethodHandle addI, addL;
+    static {
+        addI = findStatic("addI", int.class, int.class, int.class);
+        addL = findStatic("addL", Object.class, Object.class, Object.class);
+    }
+
+    private static Object list8ints(int a, int b, int c, int d, int e, int f, int g, int h) {
+        return Arrays.asList(a, b, c, d, e, f, g, h);
+    }
+    private static Object list8longs(long a, long b, long c, long d, long e, long f, long g, long h) {
+        return Arrays.asList(a, b, c, d, e, f, g, h);
+    }
+    private static final MethodHandle list8ints = findStatic("list8ints", Object.class,
+                                                             Collections.nCopies(8, int.class));
+    private static final MethodHandle list8longs = findStatic("list8longs", Object.class,
+                                                              Collections.nCopies(8, long.class));
+    private static final MethodHandle[] INT_LISTERS, LONG_LISTERS;
+    static {
+        int listerCount = list8ints.type().parameterCount() + 1;
+        INT_LISTERS  = new MethodHandle[listerCount];
+        LONG_LISTERS = new MethodHandle[listerCount];
+        MethodHandle lister = list8ints;
+        MethodHandle llister = list8longs;
+        for (int i = listerCount - 1; ; i--) {
+            INT_LISTERS[i] = lister;
+            LONG_LISTERS[i] = llister;
+            if (i == 0)  break;
+            lister  = insertArguments(lister,  i-1, (int)0);
+            llister = insertArguments(llister, i-1, (long)0);
+        }
+    }
+
+    private static Object  convI_L(int     x) { stress(); return (Object)  x; }
+    private static int     convL_I(Object  x) { stress(); return (int)     x; }
+    private static Object  convJ_L(long    x) { stress(); return (Object)  x; }
+    private static long    convL_J(Object  x) { stress(); return (long)    x; }
+    private static int     convJ_I(long    x) { stress(); return (int)     x; }
+    private static long    convI_J(int     x) { stress(); return (long)    x; }
+    private static final MethodHandle convI_L, convL_I, convJ_L, convL_J, convJ_I, convI_J;
+    static {
+        convI_L = findStatic("convI_L", Object.class, int.class);
+        convL_I = findStatic("convL_I", int.class, Object.class);
+        convJ_L = findStatic("convJ_L", Object.class, long.class);
+        convL_J = findStatic("convL_J", long.class, Object.class);
+        convJ_I = findStatic("convJ_I", int.class, long.class);
+        convI_J = findStatic("convI_J", long.class, int.class);
+    }
+
+    // stress modes:
+    private static final int REPEAT = getProperty("REPEAT", 0);
+    private static final int STRESS = getProperty("STRESS", 0);
+    private static /*v*/ int STRESS_COUNT;
+    private static final Object[] SINK = new Object[4];
+    private static void stress() {
+        if (STRESS <= 0) return;
+        int count = STRESS + (STRESS_COUNT++ & 0x1);  // non-constant value
+        for (int i = 0; i < count; i++) {
+            SINK[i % SINK.length] = new Object[STRESS + i % (SINK.length + 1)];
+        }
+    }
+
+    // verbosity:
+    private static final int VERBOSITY = getProperty("VERBOSITY", 0) + (REPEAT == 0 ? 0 : -1);
+    private static void verbose(Object a, Object b, Object c, Object d) {
+        if (VERBOSITY <= 0)  return;
+        verbose(1, a, b, c, d);
+    }
+    private static void verbose(Object a, Object b, Object c) {
+        if (VERBOSITY <= 0)  return;
+        verbose(1, a, b, c);
+    }
+    private static void verbose(int level, Object a, Object... bcd) {
+        if (level > VERBOSITY)  return;
+        String m = a.toString();
+        if (bcd != null && bcd.length > 0) {
+            List<Object> l = new ArrayList<>(bcd.length);
+            for (Object x : bcd) {
+                if (x instanceof Object[])  x = Arrays.asList((Object[])x);
+                if (x instanceof int[])     x = Arrays.toString((int[])x);
+                if (x instanceof long[])    x = Arrays.toString((long[])x);
+                l.add(x);
+            }
+            m = m+Arrays.asList(bcd);
+        }
+        System.out.println(m);
+    }
+    String testOnly;
+    String testOnlyTests;
+    private boolean startTest(String name) {
+        if (testOnly != null && !testOnly.contains(name))
+            return false;
+        verbose(0, "["+name+"]");
+        testOnlyTests = (testOnlyTests == null) ? name : testOnlyTests+" "+name;
+        return true;
+    }
+
+}
--- a/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/AsynchronousServerSocketChannel/Basic.java	Wed May 18 13:19:32 2011 +0200
@@ -29,7 +29,7 @@
 
 import java.nio.channels.*;
 import java.net.*;
-import static java.net.StandardSocketOption.*;
+import static java.net.StandardSocketOptions.*;
 import java.io.IOException;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
--- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java	Wed May 18 13:19:32 2011 +0200
@@ -29,7 +29,7 @@
 
 import java.nio.ByteBuffer;
 import java.nio.channels.*;
-import static java.net.StandardSocketOption.*;
+import static java.net.StandardSocketOptions.*;
 import java.net.*;
 import java.util.Random;
 import java.util.concurrent.*;
@@ -383,7 +383,7 @@
         // write bytes and close connection
         SocketChannel sc = server.accept();
         ByteBuffer src = genBuffer();
-        sc.setOption(StandardSocketOption.SO_SNDBUF, src.remaining());
+        sc.setOption(StandardSocketOptions.SO_SNDBUF, src.remaining());
         while (src.hasRemaining())
             sc.write(src);
         sc.close();
--- a/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/DatagramChannel/BasicMulticastTests.java	Wed May 18 13:19:32 2011 +0200
@@ -52,7 +52,7 @@
             StandardProtocolFamily.INET : StandardProtocolFamily.INET6;
 
         DatagramChannel dc = DatagramChannel.open(family)
-            .setOption(StandardSocketOption.SO_REUSEADDR, true)
+            .setOption(StandardSocketOptions.SO_REUSEADDR, true)
             .bind(new InetSocketAddress(source, 0));
 
         // check existing key is returned
@@ -115,7 +115,7 @@
         System.out.println("Exception Tests");
 
         DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
-            .setOption(StandardSocketOption.SO_REUSEADDR, true)
+            .setOption(StandardSocketOptions.SO_REUSEADDR, true)
             .bind(new InetSocketAddress(0));
 
         InetAddress group = InetAddress.getByName("225.4.5.6");
--- a/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java	Wed May 18 13:19:32 2011 +0200
@@ -59,7 +59,7 @@
             StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
         DatagramChannel dc = DatagramChannel.open(family)
             .bind(new InetSocketAddress(local, 0))
-            .setOption(StandardSocketOption.IP_MULTICAST_IF, nif);
+            .setOption(StandardSocketOptions.IP_MULTICAST_IF, nif);
         int id = rand.nextInt();
         byte[] msg = Integer.toString(id).getBytes("UTF-8");
         ByteBuffer buf = ByteBuffer.wrap(msg);
@@ -146,7 +146,7 @@
         System.out.format("\nTest DatagramChannel to %s socket\n", family.name());
         try (DatagramChannel dc = (family == UNSPEC) ?
                 DatagramChannel.open() : DatagramChannel.open(family)) {
-            dc.setOption(StandardSocketOption.SO_REUSEADDR, true)
+            dc.setOption(StandardSocketOptions.SO_REUSEADDR, true)
               .bind(new InetSocketAddress(0));
 
             // join group
--- a/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/DatagramChannel/SocketOptionTests.java	Wed May 18 13:19:32 2011 +0200
@@ -31,7 +31,7 @@
 import java.net.*;
 import java.io.IOException;
 import java.util.*;
-import static java.net.StandardSocketOption.*;
+import static java.net.StandardSocketOptions.*;
 
 public class SocketOptionTests {
 
--- a/jdk/test/java/nio/channels/FileChannel/ClosedByInterrupt.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/FileChannel/ClosedByInterrupt.java	Wed May 18 13:19:32 2011 +0200
@@ -52,13 +52,16 @@
                 fc.write(bb);
         }
 
-        // test with 1-8 concurrent threads
-        for (int i=1; i<=8; i++) {
+        // test with 1-16 concurrent threads
+        for (int i=1; i<=16; i++) {
             System.out.format("%d thread(s)%n", i);
             test(f, i);
             if (failed)
                 break;
         }
+
+        if (failed)
+            throw new RuntimeException("Test failed");
     }
 
     /**
@@ -132,12 +135,14 @@
                         // give the interruptible thread a chance
                         try {
                             Thread.sleep(rand.nextInt(50));
-                        } catch (InterruptedException ignore) { }
+                        } catch (InterruptedException e) {
+                            unexpected(e);
+                        }
                     }
                 }
             } catch (ClosedByInterruptException e) {
                 if (interruptible) {
-                    if (Thread.currentThread().isInterrupted()) {
+                    if (Thread.interrupted()) {
                         expected(e + " thrown and interrupt status set");
                     } else {
                         unexpected(e + " thrown but interrupt status not set");
@@ -158,7 +163,7 @@
     }
 
     static void expected(Exception e) {
-        System.out.format("%s (not expected)%n", e);
+        System.out.format("%s (expected)%n", e);
     }
 
     static void expected(String msg) {
--- a/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/ServerSocketChannel/SocketOptionTests.java	Wed May 18 13:19:32 2011 +0200
@@ -32,7 +32,7 @@
 import java.net.*;
 import java.io.IOException;
 import java.util.*;
-import static java.net.StandardSocketOption.*;
+import static java.net.StandardSocketOptions.*;
 
 public class SocketOptionTests {
 
--- a/jdk/test/java/nio/channels/SocketChannel/Shutdown.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/SocketChannel/Shutdown.java	Wed May 18 13:19:32 2011 +0200
@@ -39,7 +39,7 @@
     static void acceptAndReset(ServerSocketChannel ssc) throws IOException {
         SocketChannel peer = ssc.accept();
         try {
-            peer.setOption(StandardSocketOption.SO_LINGER, 0);
+            peer.setOption(StandardSocketOptions.SO_LINGER, 0);
             peer.configureBlocking(false);
             peer.write(ByteBuffer.wrap(new byte[128*1024]));
         } finally {
--- a/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/channels/SocketChannel/SocketOptionTests.java	Wed May 18 13:19:32 2011 +0200
@@ -32,7 +32,7 @@
 import java.net.*;
 import java.io.IOException;
 import java.util.*;
-import static java.net.StandardSocketOption.*;
+import static java.net.StandardSocketOptions.*;
 
 public class SocketOptionTests {
 
--- a/jdk/test/java/nio/charset/StandardCharset/Standard.java	Tue May 17 00:56:01 2011 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please 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 4884238
- * @summary Test standard charset name constants.
- * @author Mike Duigou
- * @run main Standard
- */
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.io.*;
-import java.nio.charset.*;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-public class Standard {
-
-    private final static String standardCharsets[] = {
-        "US-ASCII", "ISO-8859-1", "UTF-8",
-        "UTF-16BE", "UTF-16LE", "UTF-16" };
-
-    public static void realMain(String[] args) {
-        check(StandardCharset.US_ASCII instanceof Charset);
-        check(StandardCharset.ISO_8859_1 instanceof Charset);
-        check(StandardCharset.UTF_8 instanceof Charset);
-        check(StandardCharset.UTF_16BE instanceof Charset);
-        check(StandardCharset.UTF_16LE instanceof Charset);
-        check(StandardCharset.UTF_16 instanceof Charset);
-
-        check("US-ASCII".equals(StandardCharset.US_ASCII.name()));
-        check("ISO-8859-1".equals(StandardCharset.ISO_8859_1.name()));
-        check("UTF-8".equals(StandardCharset.UTF_8.name()));
-        check("UTF-16BE".equals(StandardCharset.UTF_16BE.name()));
-        check("UTF-16LE".equals(StandardCharset.UTF_16LE.name()));
-        check("UTF-16".equals(StandardCharset.UTF_16.name()));
-
-        Set<String> charsets = new HashSet<>();
-        Field standardCharsetFields[] = StandardCharset.class.getFields();
-
-        for(Field charsetField : standardCharsetFields) {
-            check(StandardCharset.class == charsetField.getDeclaringClass());
-            check(Modifier.isFinal(charsetField.getModifiers()));
-            check(Modifier.isStatic(charsetField.getModifiers()));
-            check(Modifier.isPublic(charsetField.getModifiers()));
-            Object value;
-            try {
-                value = charsetField.get(null);
-            } catch(IllegalAccessException failure) {
-                unexpected(failure);
-                continue;
-            }
-            check(value instanceof Charset);
-            charsets.add(((Charset)value).name());
-        }
-
-        check(charsets.containsAll(Arrays.asList(standardCharsets)));
-        charsets.removeAll(Arrays.asList(standardCharsets));
-        check(charsets.isEmpty());
-    }
-
-    //--------------------- Infrastructure ---------------------------
-    static volatile int passed = 0, failed = 0;
-    static void pass() { passed++; }
-    static void fail() { failed++; Thread.dumpStack(); }
-    static void fail(String msg) { System.out.println(msg); fail(); }
-    static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
-    static void check(boolean cond) { if (cond) pass(); else fail(); }
-    static void equal(Object x, Object y) {
-        if (x == null ? y == null : x.equals(y)) pass();
-        else {System.out.println(x + " not equal to " + y); fail();}}
-    static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}
-    public static void main(String[] args) throws Throwable {
-        try { realMain(args); } catch (Throwable t) { unexpected(t); }
-
-        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
-        if (failed > 0) throw new Exception("Some tests failed");
-    }
-    private static abstract class Fun {abstract void f() throws Throwable;}
-    private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
-          for (Fun f : fs)
-              try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
-              catch (Throwable t) {
-                  if (k.isAssignableFrom(t.getClass())) pass();
-                  else unexpected(t);}}
-    static byte[] serializedForm(Object obj) {
-        try {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            new ObjectOutputStream(baos).writeObject(obj);
-            return baos.toByteArray();
-        } catch (IOException e) { throw new Error(e); }}
-    static Object readObject(byte[] bytes)
-        throws IOException, ClassNotFoundException {
-        InputStream is = new ByteArrayInputStream(bytes);
-        return new ObjectInputStream(is).readObject();}
-    @SuppressWarnings("unchecked")
-    static <T> T serialClone(T obj) {
-        try { return (T) readObject(serializedForm(obj)); }
-        catch (Exception e) { throw new Error(e); }}
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/charset/StandardCharsets/Standard.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 4884238
+ * @summary Test standard charset name constants.
+ * @author Mike Duigou
+ * @run main Standard
+ */
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.io.*;
+import java.nio.charset.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Standard {
+
+    private final static String standardCharsets[] = {
+        "US-ASCII", "ISO-8859-1", "UTF-8",
+        "UTF-16BE", "UTF-16LE", "UTF-16" };
+
+    public static void realMain(String[] args) {
+        check(StandardCharsets.US_ASCII instanceof Charset);
+        check(StandardCharsets.ISO_8859_1 instanceof Charset);
+        check(StandardCharsets.UTF_8 instanceof Charset);
+        check(StandardCharsets.UTF_16BE instanceof Charset);
+        check(StandardCharsets.UTF_16LE instanceof Charset);
+        check(StandardCharsets.UTF_16 instanceof Charset);
+
+        check("US-ASCII".equals(StandardCharsets.US_ASCII.name()));
+        check("ISO-8859-1".equals(StandardCharsets.ISO_8859_1.name()));
+        check("UTF-8".equals(StandardCharsets.UTF_8.name()));
+        check("UTF-16BE".equals(StandardCharsets.UTF_16BE.name()));
+        check("UTF-16LE".equals(StandardCharsets.UTF_16LE.name()));
+        check("UTF-16".equals(StandardCharsets.UTF_16.name()));
+
+        Set<String> charsets = new HashSet<>();
+        Field standardCharsetFields[] = StandardCharsets.class.getFields();
+
+        for(Field charsetField : standardCharsetFields) {
+            check(StandardCharsets.class == charsetField.getDeclaringClass());
+            check(Modifier.isFinal(charsetField.getModifiers()));
+            check(Modifier.isStatic(charsetField.getModifiers()));
+            check(Modifier.isPublic(charsetField.getModifiers()));
+            Object value;
+            try {
+                value = charsetField.get(null);
+            } catch(IllegalAccessException failure) {
+                unexpected(failure);
+                continue;
+            }
+            check(value instanceof Charset);
+            charsets.add(((Charset)value).name());
+        }
+
+        check(charsets.containsAll(Arrays.asList(standardCharsets)));
+        charsets.removeAll(Arrays.asList(standardCharsets));
+        check(charsets.isEmpty());
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() { passed++; }
+    static void fail() { failed++; Thread.dumpStack(); }
+    static void fail(String msg) { System.out.println(msg); fail(); }
+    static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
+    static void check(boolean cond) { if (cond) pass(); else fail(); }
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else {System.out.println(x + " not equal to " + y); fail();}}
+    static void equal2(Object x, Object y) {equal(x, y); equal(y, x);}
+    public static void main(String[] args) throws Throwable {
+        try { realMain(args); } catch (Throwable t) { unexpected(t); }
+
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new Exception("Some tests failed");
+    }
+    private static abstract class Fun {abstract void f() throws Throwable;}
+    private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
+          for (Fun f : fs)
+              try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
+              catch (Throwable t) {
+                  if (k.isAssignableFrom(t.getClass())) pass();
+                  else unexpected(t);}}
+    static byte[] serializedForm(Object obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            new ObjectOutputStream(baos).writeObject(obj);
+            return baos.toByteArray();
+        } catch (IOException e) { throw new Error(e); }}
+    static Object readObject(byte[] bytes)
+        throws IOException, ClassNotFoundException {
+        InputStream is = new ByteArrayInputStream(bytes);
+        return new ObjectInputStream(is).readObject();}
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try { return (T) readObject(serializedForm(obj)); }
+        catch (Exception e) { throw new Error(e); }}
+
+}
--- a/jdk/test/java/nio/file/Files/CheckPermissions.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/file/Files/CheckPermissions.java	Wed May 18 13:19:32 2011 +0200
@@ -540,7 +540,7 @@
 
             try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
                 prepare();
-                testdir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
+                testdir.register(watcher, StandardWatchEventKinds.ENTRY_DELETE);
                 assertCheckRead(testdir);
             }
 
--- a/jdk/test/java/nio/file/WatchService/Basic.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/file/WatchService/Basic.java	Wed May 18 13:19:32 2011 +0200
@@ -29,7 +29,7 @@
  */
 
 import java.nio.file.*;
-import static java.nio.file.StandardWatchEventKind.*;
+import static java.nio.file.StandardWatchEventKinds.*;
 import java.nio.file.attribute.*;
 import java.io.*;
 import java.util.*;
@@ -100,7 +100,7 @@
             // remove key and check that we got the ENTRY_CREATE event
             takeExpectedKey(watcher, myKey);
             checkExpectedEvent(myKey.pollEvents(),
-                StandardWatchEventKind.ENTRY_CREATE, name);
+                StandardWatchEventKinds.ENTRY_CREATE, name);
 
             System.out.println("reset key");
             if (!myKey.reset())
@@ -121,7 +121,7 @@
             Files.delete(file);
             takeExpectedKey(watcher, myKey);
             checkExpectedEvent(myKey.pollEvents(),
-                StandardWatchEventKind.ENTRY_DELETE, name);
+                StandardWatchEventKinds.ENTRY_DELETE, name);
 
             System.out.println("reset key");
             if (!myKey.reset())
@@ -149,7 +149,7 @@
             // remove key and check that we got the ENTRY_MODIFY event
             takeExpectedKey(watcher, myKey);
             checkExpectedEvent(myKey.pollEvents(),
-                StandardWatchEventKind.ENTRY_MODIFY, name);
+                StandardWatchEventKinds.ENTRY_MODIFY, name);
             System.out.println("OKAY");
 
             // done
@@ -424,7 +424,7 @@
             // check that key1 got ENTRY_CREATE
             takeExpectedKey(watcher1, key1);
             checkExpectedEvent(key1.pollEvents(),
-                StandardWatchEventKind.ENTRY_CREATE, name2);
+                StandardWatchEventKinds.ENTRY_CREATE, name2);
 
             // check that key2 got zero events
             WatchKey key = watcher2.poll();
@@ -437,7 +437,7 @@
             // check that key2 got ENTRY_DELETE
             takeExpectedKey(watcher2, key2);
             checkExpectedEvent(key2.pollEvents(),
-                StandardWatchEventKind.ENTRY_DELETE, name1);
+                StandardWatchEventKinds.ENTRY_DELETE, name1);
 
             // check that key1 got zero events
             key = watcher1.poll();
@@ -458,7 +458,7 @@
             Files.createFile(file1);
             takeExpectedKey(watcher2, key2);
             checkExpectedEvent(key2.pollEvents(),
-                StandardWatchEventKind.ENTRY_CREATE, name1);
+                StandardWatchEventKinds.ENTRY_CREATE, name1);
 
             System.out.println("OKAY");
 
--- a/jdk/test/java/nio/file/WatchService/FileTreeModifier.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/file/WatchService/FileTreeModifier.java	Wed May 18 13:19:32 2011 +0200
@@ -28,7 +28,7 @@
  */
 
 import java.nio.file.*;
-import static java.nio.file.StandardWatchEventKind.*;
+import static java.nio.file.StandardWatchEventKinds.*;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.*;
--- a/jdk/test/java/nio/file/WatchService/LotsOfEvents.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/file/WatchService/LotsOfEvents.java	Wed May 18 13:19:32 2011 +0200
@@ -29,7 +29,7 @@
  */
 
 import java.nio.file.*;
-import static java.nio.file.StandardWatchEventKind.*;
+import static java.nio.file.StandardWatchEventKinds.*;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.*;
--- a/jdk/test/java/nio/file/WatchService/SensitivityModifier.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/file/WatchService/SensitivityModifier.java	Wed May 18 13:19:32 2011 +0200
@@ -29,7 +29,7 @@
  */
 
 import java.nio.file.*;
-import static java.nio.file.StandardWatchEventKind.*;
+import static java.nio.file.StandardWatchEventKinds.*;
 import java.io.OutputStream;
 import java.io.IOException;
 import java.util.Random;
--- a/jdk/test/java/nio/file/WatchService/WithSecurityManager.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/java/nio/file/WatchService/WithSecurityManager.java	Wed May 18 13:19:32 2011 +0200
@@ -66,7 +66,7 @@
         // attempt to register directory
         try {
             dir.register(dir.getFileSystem().newWatchService(),
-                         new WatchEvent.Kind<?>[]{ StandardWatchEventKind.ENTRY_CREATE },
+                         new WatchEvent.Kind<?>[]{ StandardWatchEventKinds.ENTRY_CREATE },
                          modifiers);
             if (expectedToFail)
                 throw new RuntimeException("SecurityException not thrown");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Bidi/Bug7041232.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7041232
+ * @summary verify that an unexpected exception isn't thrown for unnatural data to keep backward compatibility with JDK 6.
+ */
+import java.text.*;
+
+public class Bug7041232 {
+
+    public static void main(String[] args) {
+        String UnicodeChars;
+        StringBuffer sb = new StringBuffer();
+
+        // Generates String which includes U+2028(line separator) and
+        // U+2029(paragraph separator)
+        for (int i = 0x2000; i < 0x2100; i++) {
+            sb.append((char)i);
+        }
+        UnicodeChars = sb.toString();
+
+        Bidi bidi = new Bidi(UnicodeChars, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+        bidi.createLineBidi(0, UnicodeChars.length());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/LoggingDeadlock3.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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     6487638 7041595
+ * @summary Calling LogManager.addLogger() and Logger.getLogger() cause deadlock
+ * @author  Serguei Spitsyn
+ * @build LoggingDeadlock3
+ * @run main/timeout=15 LoggingDeadlock3
+ */
+
+import java.io.*;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+public class LoggingDeadlock3 {
+  static final int         ITER_CNT   = 50000;
+  static final String      MSG_PASSED = "LoggingDeadlock3: passed";
+  static final LogManager  logMgr     = LogManager.getLogManager();
+  static final PrintStream out        = System.out;
+
+  public static void main(String args[]) throws Exception {
+    String tstSrc = System.getProperty("test.src");
+    File   fname  = new File(tstSrc, "LoggingDeadlock3.props");
+    String prop   = fname.getCanonicalPath();
+    System.setProperty("java.util.logging.config.file", prop);
+    logMgr.readConfiguration();
+
+    Thread t1 = new Thread(new AddLogger());
+    Thread t2 = new Thread(new GetLogger());
+    t1.start(); t2.start();
+    t1.join();  t2.join();
+    out.println("\n" + MSG_PASSED);
+  }
+
+  public static class MyLogger extends Logger {
+    protected MyLogger(String name) { super(name, null); }
+  }
+
+  public static class GetLogger implements Runnable {
+    public void run() {
+      for (int cnt = 0; cnt < ITER_CNT * 8; cnt++) {
+        Logger logger = Logger.getLogger("com.sun.Hello"+cnt/10);
+        if (cnt % 1000  == 0) out.print("1");
+        if (cnt % 10000 == 0) out.println();
+      }
+    }
+  }
+
+  public static class AddLogger implements Runnable {
+    public void run() {
+      for (int cnt = 0; cnt < ITER_CNT; cnt++) {
+        Logger addLogger = new MyLogger("com.sun.Hello"+cnt);
+        logMgr.addLogger(addLogger);
+        if (cnt % 100  == 0) out.print("2");
+        if (cnt % 1000 == 0) out.println();
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/LoggingDeadlock3.props	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,3 @@
+com.sun.LEVEL=FINE
+com.sun.level=FINE
+com.sun.Hello.level=INFO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/LoggingDeadlock4.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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     6977677
+ * @summary Deadlock between LogManager.<clinit> and Logger.getLogger()
+ * @author  Daniel D. Daugherty
+ * @build LoggingDeadlock4
+ * @run main/timeout=15 LoggingDeadlock4
+ */
+
+import java.awt.Container;
+import java.util.concurrent.CountDownLatch;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+public class LoggingDeadlock4 {
+    private static CountDownLatch barrier      = new CountDownLatch(1);
+    private static CountDownLatch lmIsRunning  = new CountDownLatch(1);
+    private static CountDownLatch logIsRunning = new CountDownLatch(1);
+
+    public static void main(String[] args) {
+        System.out.println("main: LoggingDeadlock4 is starting.");
+
+        // Loading the java.awt.Container class will create a
+        // sun.util.logging.PlatformLogger$JavaLogger object
+        // that has to be redirected when the LogManager class
+        // is initialized. This can cause a deadlock between
+        // LogManager.<clinit> and Logger.getLogger().
+        try {
+            Class.forName("java.awt.Container");
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException("Test failed: could not load"
+                + " java.awt.Container." + cnfe);
+        }
+
+        Thread lmThread = new Thread("LogManagerThread") {
+            public void run() {
+                // let main know LogManagerThread is running
+                lmIsRunning.countDown();
+
+                System.out.println(Thread.currentThread().getName()
+                    + ": is running.");
+
+                try {
+                    barrier.await();  // wait for race to start
+                } catch (InterruptedException e) {
+                }
+
+                LogManager manager = LogManager.getLogManager();
+            }
+        };
+        lmThread.start();
+
+        Thread logThread = new Thread("LoggerThread") {
+            public void run() {
+                // let main know LoggerThread is running
+                logIsRunning.countDown();
+
+                System.out.println(Thread.currentThread().getName()
+                    + ": is running.");
+
+                try {
+                    barrier.await();  // wait for race to start
+                } catch (InterruptedException e) {
+                }
+
+                Logger foo = Logger.getLogger("foo logger");
+            }
+        };
+        logThread.start();
+
+        try {
+            // wait for LogManagerThread and LoggerThread to get going
+            lmIsRunning.await();
+            logIsRunning.await();
+        } catch (InterruptedException e) {
+        }
+
+        barrier.countDown();  // start the race
+
+        try {
+            lmThread.join();
+            logThread.join();
+        } catch (InterruptedException ie) {
+        }
+
+        System.out.println("main: LoggingDeadlock4 is done.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/timer/StartTest.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2008, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 6659215
+ * @summary Test on timer start method with past notifications
+ * @author Shanliang JIANG
+ * @run clean StartTest
+ * @run build StartTest
+ * @run main StartTest
+ */
+
+import java.util.Date;
+import javax.management.timer.Timer;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+
+public class StartTest {
+    public static void main(String[] args) throws Exception {
+        System.out.println(
+            ">>> Test on timer start method with past notifications.");
+
+        System.out.println(">>> Create a Timer object.");
+        Timer timer = new Timer();
+
+        System.out.println(
+            ">>> Set the flag (setSendPastNotification) to true.");
+        timer.setSendPastNotifications(true);
+
+        timer.addNotificationListener(myListener, null, null);
+
+        System.out.println(">>> Add notifications: " + SENT);
+
+        Date date = new Date();
+        for (int i = 0; i < SENT; i++) {
+            timer.addNotification(
+                "testType" + i, "testMsg" + i, "testData" + i, date);
+        }
+
+        System.out.println(">>> The notifications should be sent at " + date);
+        System.out.println(">>> Sleep 100 ms to have past notifications.");
+        Thread.sleep(100);
+
+        System.out.println(">>> Start the timer at " + new Date());
+        timer.start();
+
+        System.out.println(">>> Stop the timer.");
+        Thread.sleep(100);
+        stopping = true;
+        timer.stop();
+
+        if (received != SENT) {
+            throw new RuntimeException(
+                "Expected to receive " + SENT + " but got " + received);
+        }
+
+        System.out.println(">>> Received all expected notifications.");
+
+        System.out.println(">>> Bye bye!");
+    }
+
+    private static NotificationListener myListener =
+        new NotificationListener() {
+            public void handleNotification(Notification n, Object hb) {
+                if (!stopping) {
+                    received++;
+                    System.out.println(
+                        ">>> myListener-handleNotification: received " +
+                        n.getSequenceNumber());
+            }
+        }
+    };
+
+    private static int SENT = 10;
+    private static volatile int received = 0;
+    private static volatile boolean stopping = false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JComboBox/7031551/bug7031551.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7031551
+ * @summary Generics: JComboBox
+ * @author Pavel Porvatov
+ */
+
+import javax.swing.*;
+import java.util.Vector;
+
+public class bug7031551 {
+
+    private static final String TEST_ELEMENT1 = "Test1";
+    private static final String TEST_ELEMENT2 = "Test2";
+    private static final String TEST_ELEMENT3 = "Test3";
+
+    /**
+     * @param args the command line arguments
+     */
+    @SuppressWarnings("unchecked")
+    public static void main(String[] args) {
+        testRawSignatures();
+        testGenericSignatures();
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void testRawSignatures() {
+        // Test JComboBox
+        ComboBoxModel rawTestModel = new DefaultComboBoxModel();
+
+        JComboBox rawTestComboBox = new JComboBox();
+        rawTestComboBox = new JComboBox(rawTestModel);
+        rawTestComboBox = new JComboBox(new Object[]{TEST_ELEMENT1});
+        rawTestComboBox = new JComboBox(new Vector());
+
+        Object unused1 = rawTestComboBox.getPrototypeDisplayValue();
+        rawTestComboBox.setPrototypeDisplayValue(TEST_ELEMENT1);
+
+        ListCellRenderer unused2 = rawTestComboBox.getRenderer();
+        rawTestComboBox.setRenderer(new DefaultListCellRenderer());
+
+        ComboBoxModel unused3 = rawTestComboBox.getModel();
+        rawTestComboBox.setModel(rawTestModel);
+
+        rawTestComboBox.addItem(TEST_ELEMENT2);
+        rawTestComboBox.insertItemAt(TEST_ELEMENT3, 1);
+        rawTestComboBox.removeItem(TEST_ELEMENT2);
+        assertEquals(rawTestComboBox.getItemAt(0), TEST_ELEMENT3);
+        rawTestComboBox.removeAllItems();
+
+        // Test DefaultComboBoxModel
+        DefaultComboBoxModel testModel = new DefaultComboBoxModel();
+        testModel = new DefaultComboBoxModel(new Vector());
+        testModel = new DefaultComboBoxModel(new Object[]{TEST_ELEMENT1});
+
+        testModel.addElement(TEST_ELEMENT2);
+        testModel.insertElementAt(TEST_ELEMENT3, 1);
+        assertEquals(testModel.getElementAt(2), TEST_ELEMENT2);
+    }
+
+    private static void testGenericSignatures() {
+        // Test JComboBox
+        ComboBoxModel<String> stringTestModel = new DefaultComboBoxModel<String>();
+
+        JComboBox<String> stringTestComboBox = new JComboBox<String>();
+        stringTestComboBox = new JComboBox<String>(stringTestModel);
+        stringTestComboBox = new JComboBox<String>(new String[]{TEST_ELEMENT1});
+        stringTestComboBox = new JComboBox<String>(new Vector<String>());
+
+        String unused1 = stringTestComboBox.getPrototypeDisplayValue();
+        stringTestComboBox.setPrototypeDisplayValue(TEST_ELEMENT1);
+
+        ListCellRenderer<? super String> unused2 = stringTestComboBox.getRenderer();
+        stringTestComboBox.setRenderer(new DefaultListCellRenderer());
+
+        ComboBoxModel unused3 = stringTestComboBox.getModel();
+        stringTestComboBox.setModel(stringTestModel);
+
+        stringTestComboBox.addItem(TEST_ELEMENT2);
+        stringTestComboBox.insertItemAt(TEST_ELEMENT3, 1);
+        stringTestComboBox.removeItem(TEST_ELEMENT2);
+        assertEquals(stringTestComboBox.getItemAt(0), TEST_ELEMENT3);
+        stringTestComboBox.removeAllItems();
+
+        // Test DefaultComboBoxModel
+        DefaultComboBoxModel<String> testModel = new DefaultComboBoxModel<String>();
+        testModel = new DefaultComboBoxModel<String>(new Vector<String>());
+        testModel = new DefaultComboBoxModel<String>(new String[]{TEST_ELEMENT1});
+
+        testModel.addElement(TEST_ELEMENT2);
+        testModel.insertElementAt(TEST_ELEMENT3, 1);
+        assertEquals(testModel.getElementAt(2), TEST_ELEMENT2);
+    }
+
+    private static void assertEquals(Object expectedObject, Object actualObject) {
+        if (!expectedObject.equals(actualObject)) {
+            throw new RuntimeException("Expected: " + expectedObject + " but was: " + actualObject);
+        }
+    }
+}
+
--- a/jdk/test/javax/swing/JTable/6788484/bug6788484.java	Tue May 17 00:56:01 2011 -0700
+++ b/jdk/test/javax/swing/JTable/6788484/bug6788484.java	Wed May 18 13:19:32 2011 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -24,9 +24,17 @@
 /* @test
    @bug 6788484
    @summary NPE in DefaultTableCellHeaderRenderer.getColumnSortOrder() with null table
+   @compile -XDignore.symbol.file=true bug6788484.java
    @author Alexander Potochkin
    @run main bug6788484
 */
+
+/*
+ * Compile with -XDignore.symbol.file=true option as a workaround for
+ * specific behaviour described in 6380059 which restricts proprietary
+ * package loading
+ */
+
 import sun.swing.table.DefaultTableCellHeaderRenderer;
 
 import javax.swing.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/invoke/util/ValueConversionsTest.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,448 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test.sun.invoke.util;
+
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.Wrapper;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import org.junit.Ignore;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/* @test
+ * @summary unit tests for value-type conversion utilities
+ * @ignore This test requires a special compilation environment to access sun.inovke.util.  Run by hand.
+ * @run junit/othervm test.sun.invoke.util.ValueConversionsTest
+ * @run junit/othervm
+ *          -DValueConversionsTest.MAX_ARITY=255 -DValueConversionsTest.START_ARITY=250
+ *              test.sun.invoke.util.ValueConversionsTest
+ */
+
+// This might take a while and burn lots of metadata:
+// @run junit/othervm -DValueConversionsTest.MAX_ARITY=255 -DValueConversionsTest.EXHAUSTIVE=true test.sun.invoke.util.ValueConversionsTest
+
+/**
+ *
+ * @author jrose
+ */
+public class ValueConversionsTest {
+    private static final Class CLASS = ValueConversionsTest.class;
+    private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
+    private static final int START_ARITY = Integer.getInteger(CLASS.getSimpleName()+".START_ARITY", 0);
+    private static final boolean EXHAUSTIVE = Boolean.getBoolean(CLASS.getSimpleName()+".EXHAUSTIVE");
+
+    @Test
+    public void testUnbox() throws Throwable {
+        testUnbox(false);
+    }
+
+    @Test
+    public void testUnboxCast() throws Throwable {
+        testUnbox(true);
+    }
+
+    private void testUnbox(boolean doCast) throws Throwable {
+        //System.out.println("unbox");
+        for (Wrapper dst : Wrapper.values()) {
+            //System.out.println(dst);
+            for (Wrapper src : Wrapper.values()) {
+                testUnbox(doCast, dst, src);
+            }
+        }
+    }
+
+    private void testUnbox(boolean doCast, Wrapper dst, Wrapper src) throws Throwable {
+        boolean expectThrow = !doCast && !dst.isConvertibleFrom(src);
+        if (dst == Wrapper.OBJECT || src == Wrapper.OBJECT)  return;  // must have prims
+        if (dst == Wrapper.OBJECT)
+            expectThrow = false;  // everything (even VOID==null here) converts to OBJECT
+        try {
+            for (int n = -5; n < 10; n++) {
+                Object box = src.wrap(n);
+                switch (src) {
+                    case VOID:   assertEquals(box, null); break;
+                    case OBJECT: box = box.toString(); break;
+                    case SHORT:  assertEquals(box.getClass(), Short.class); break;
+                    default:     assertEquals(box.getClass(), src.wrapperType()); break;
+                }
+                MethodHandle unboxer;
+                if (doCast)
+                    unboxer = ValueConversions.unboxCast(dst.primitiveType());
+                else
+                    unboxer = ValueConversions.unbox(dst.primitiveType());
+                Object expResult = (box == null) ? dst.zero() : dst.wrap(box);
+                Object result = null;
+                switch (dst) {
+                    case INT:     result = (int)     unboxer.invokeExact(box); break;
+                    case LONG:    result = (long)    unboxer.invokeExact(box); break;
+                    case FLOAT:   result = (float)   unboxer.invokeExact(box); break;
+                    case DOUBLE:  result = (double)  unboxer.invokeExact(box); break;
+                    case CHAR:    result = (char)    unboxer.invokeExact(box); break;
+                    case BYTE:    result = (byte)    unboxer.invokeExact(box); break;
+                    case SHORT:   result = (short)   unboxer.invokeExact(box); break;
+                    case OBJECT:  result = (Object)  unboxer.invokeExact(box); break;
+                    case BOOLEAN: result = (boolean) unboxer.invokeExact(box); break;
+                    case VOID:    result = null;     unboxer.invokeExact(box); break;
+                }
+                if (expectThrow) {
+                    expResult = "(need an exception)";
+                }
+                assertEquals("(doCast,expectThrow,dst,src,n,box)="+Arrays.asList(doCast,expectThrow,dst,src,n,box),
+                             expResult, result);
+            }
+        } catch (RuntimeException ex) {
+            if (expectThrow)  return;
+            System.out.println("Unexpected throw for (doCast,expectThrow,dst,src)="+Arrays.asList(doCast,expectThrow,dst,src));
+            throw ex;
+        }
+    }
+
+    @Test
+    public void testUnboxRaw() throws Throwable {
+        //System.out.println("unboxRaw");
+        for (Wrapper w : Wrapper.values()) {
+            if (w == Wrapper.OBJECT)  continue;  // skip this; no raw form
+            //System.out.println(w);
+            for (int n = -5; n < 10; n++) {
+                Object box = w.wrap(n);
+                long expResult = w.unwrapRaw(box);
+                Object box2 = w.wrapRaw(expResult);
+                assertEquals(box, box2);
+                MethodHandle unboxer = ValueConversions.unboxRaw(w.primitiveType());
+                long result = -1;
+                switch (w) {
+                    case INT:     result = (int)  unboxer.invokeExact(box); break;
+                    case LONG:    result = (long) unboxer.invokeExact(box); break;
+                    case FLOAT:   result = (int)  unboxer.invokeExact(box); break;
+                    case DOUBLE:  result = (long) unboxer.invokeExact(box); break;
+                    case CHAR:    result = (int)  unboxer.invokeExact(box); break;
+                    case BYTE:    result = (int)  unboxer.invokeExact(box); break;
+                    case SHORT:   result = (int)  unboxer.invokeExact(box); break;
+                    case BOOLEAN: result = (int)  unboxer.invokeExact(box); break;
+                    case VOID:    result = (int)  unboxer.invokeExact(box); break;
+                }
+                assertEquals("(w,n,box)="+Arrays.asList(w,n,box),
+                             expResult, result);
+            }
+        }
+    }
+
+    @Test
+    public void testBox() throws Throwable {
+        //System.out.println("box");
+        for (Wrapper w : Wrapper.values()) {
+            if (w == Wrapper.VOID)  continue;  // skip this; no unboxed form
+            //System.out.println(w);
+            for (int n = -5; n < 10; n++) {
+                Object box = w.wrap(n);
+                MethodHandle boxer = ValueConversions.box(w.primitiveType());
+                Object expResult = box;
+                Object result = null;
+                switch (w) {
+                    case INT:     result = boxer.invokeExact((int)n); break;
+                    case LONG:    result = boxer.invokeExact((long)n); break;
+                    case FLOAT:   result = boxer.invokeExact((float)n); break;
+                    case DOUBLE:  result = boxer.invokeExact((double)n); break;
+                    case CHAR:    result = boxer.invokeExact((char)n); break;
+                    case BYTE:    result = boxer.invokeExact((byte)n); break;
+                    case SHORT:   result = boxer.invokeExact((short)n); break;
+                    case OBJECT:  result = boxer.invokeExact((Object)n); break;
+                    case BOOLEAN: result = boxer.invokeExact((n & 1) != 0); break;
+                }
+                assertEquals("(dst,src,n,box)="+Arrays.asList(w,w,n,box),
+                             expResult, result);
+            }
+        }
+    }
+
+    @Test
+    public void testBoxRaw() throws Throwable {
+        //System.out.println("boxRaw");
+        for (Wrapper w : Wrapper.values()) {
+            if (w == Wrapper.VOID)  continue;  // skip this; no unboxed form
+            if (w == Wrapper.OBJECT)  continue;  // skip this; no raw form
+            //System.out.println(w);
+            for (int n = -5; n < 10; n++) {
+                Object box = w.wrap(n);
+                long   raw = w.unwrapRaw(box);
+                Object expResult = box;
+                MethodHandle boxer = ValueConversions.boxRaw(w.primitiveType());
+                Object result = null;
+                switch (w) {
+                case INT:     result = boxer.invokeExact((int)raw); break;
+                case LONG:    result = boxer.invokeExact(raw); break;
+                case FLOAT:   result = boxer.invokeExact((int)raw); break;
+                case DOUBLE:  result = boxer.invokeExact(raw); break;
+                case CHAR:    result = boxer.invokeExact((int)raw); break;
+                case BYTE:    result = boxer.invokeExact((int)raw); break;
+                case SHORT:   result = boxer.invokeExact((int)raw); break;
+                case BOOLEAN: result = boxer.invokeExact((int)raw); break;
+                }
+                assertEquals("(dst,src,n,box)="+Arrays.asList(w,w,n,box),
+                             expResult, result);
+            }
+        }
+    }
+
+    @Test
+    public void testReboxRaw() throws Throwable {
+        //System.out.println("reboxRaw");
+        for (Wrapper w : Wrapper.values()) {
+            Wrapper pw = Wrapper.forPrimitiveType(w.rawPrimitiveType());
+            if (w == Wrapper.VOID)  continue;  // skip this; no unboxed form
+            if (w == Wrapper.OBJECT)  continue;  // skip this; no raw form
+            //System.out.println(w);
+            for (int n = -5; n < 10; n++) {
+                Object box = w.wrap(n);
+                Object raw = pw.wrap(w.unwrapRaw(box));
+                Object expResult = box;
+                MethodHandle boxer = ValueConversions.rebox(w.primitiveType());
+                Object result = null;
+                switch (w) {
+                case INT:     result = boxer.invokeExact(raw); break;
+                case LONG:    result = boxer.invokeExact(raw); break;
+                case FLOAT:   result = boxer.invokeExact(raw); break;
+                case DOUBLE:  result = boxer.invokeExact(raw); break;
+                case CHAR:    result = boxer.invokeExact(raw); break;
+                case BYTE:    result = boxer.invokeExact(raw); break;
+                case SHORT:   result = boxer.invokeExact(raw); break;
+                case BOOLEAN: result = boxer.invokeExact(raw); break;
+                }
+                assertEquals("(dst,src,n,box)="+Arrays.asList(w,w,n,box),
+                             expResult, result);
+            }
+        }
+    }
+
+    @Test
+    public void testCast() throws Throwable {
+        //System.out.println("cast");
+        Class<?>[] types = { Object.class, Serializable.class, String.class, Number.class, Integer.class };
+        Object[] objects = { new Object(), Boolean.FALSE,      "hello",      (Long)12L,    (Integer)6    };
+        for (Class<?> dst : types) {
+            MethodHandle caster = ValueConversions.cast(dst);
+            assertEquals(caster.type(), ValueConversions.identity().type());
+            for (Object obj : objects) {
+                Class<?> src = obj.getClass();
+                boolean canCast;
+                if (dst.isInterface()) {
+                    canCast = true;
+                } else {
+                    canCast = dst.isAssignableFrom(src);
+                    assertEquals(canCast, dst.isInstance(obj));
+                }
+                //System.out.println("obj="+obj+" <: dst="+dst);
+                try {
+                    Object result = caster.invokeExact(obj);
+                    if (canCast)
+                        assertEquals(obj, result);
+                    else
+                        assertEquals("cast should not have succeeded", dst, obj);
+                } catch (ClassCastException ex) {
+                    if (canCast)
+                        throw ex;
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testIdentity() throws Throwable {
+        //System.out.println("identity");
+        MethodHandle id = ValueConversions.identity();
+        Object expResult = "foo";
+        Object result = id.invokeExact(expResult);
+        // compiler bug:  ValueConversions.identity().invokeExact("bar");
+        assertEquals(expResult, result);
+    }
+
+    @Test
+    public void testVarargsArray() throws Throwable {
+        //System.out.println("varargsArray");
+        final int MIN = START_ARITY;
+        final int MAX = MAX_ARITY-2;  // 253+1 would cause parameter overflow with 'this' added
+        for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, 17, MAX)) {
+            MethodHandle target = ValueConversions.varargsArray(nargs);
+            Object[] args = new Object[nargs];
+            for (int i = 0; i < nargs; i++)
+                args[i] = "#"+i;
+            Object res = target.invokeWithArguments(args);
+            assertArrayEquals(args, (Object[])res);
+        }
+    }
+
+    @Test
+    public void testVarargsReferenceArray() throws Throwable {
+        //System.out.println("varargsReferenceArray");
+        testTypedVarargsArray(Object[].class);
+        testTypedVarargsArray(String[].class);
+        testTypedVarargsArray(Number[].class);
+    }
+
+    @Test
+    public void testVarargsPrimitiveArray() throws Throwable {
+        //System.out.println("varargsPrimitiveArray");
+        testTypedVarargsArray(int[].class);
+        testTypedVarargsArray(long[].class);
+        testTypedVarargsArray(byte[].class);
+        testTypedVarargsArray(boolean[].class);
+        testTypedVarargsArray(short[].class);
+        testTypedVarargsArray(char[].class);
+        testTypedVarargsArray(float[].class);
+        testTypedVarargsArray(double[].class);
+    }
+
+    private static int nextArgCount(int nargs, int density, int MAX) {
+        if (EXHAUSTIVE)  return nargs + 1;
+        if (nargs >= MAX)  return Integer.MAX_VALUE;
+        int BOT = 20, TOP = MAX-5;
+        if (density < 10) { BOT = 10; MAX = TOP-2; }
+        if (nargs <= BOT || nargs >= TOP) {
+            ++nargs;
+        } else {
+            int bump = Math.max(1, 100 / density);
+            nargs += bump;
+            if (nargs > TOP)  nargs = TOP;
+        }
+        return nargs;
+    }
+
+    private void testTypedVarargsArray(Class<?> arrayType) throws Throwable {
+        System.out.println(arrayType.getSimpleName());
+        Class<?> elemType = arrayType.getComponentType();
+        int MIN = START_ARITY;
+        int MAX = MAX_ARITY-2;  // 253+1 would cause parameter overflow with 'this' added
+        int density = 3;
+        if (elemType == int.class || elemType == long.class)  density = 7;
+        if (elemType == long.class || elemType == double.class) { MAX /= 2; MIN /= 2; }
+        for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, density, MAX)) {
+            Object[] args = makeTestArray(elemType, nargs);
+            MethodHandle varargsArray = ValueConversions.varargsArray(arrayType, nargs);
+            MethodType vaType = varargsArray.type();
+            assertEquals(arrayType, vaType.returnType());
+            if (nargs != 0) {
+                assertEquals(elemType, vaType.parameterType(0));
+                assertEquals(elemType, vaType.parameterType(vaType.parameterCount()-1));
+            }
+            assertEquals(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)),
+                         vaType);
+            Object res = varargsArray.invokeWithArguments(args);
+            String resString = toArrayString(res);
+            assertEquals(Arrays.toString(args), resString);
+
+            MethodHandle spreader = varargsArray.asSpreader(arrayType, nargs);
+            MethodType stype = spreader.type();
+            assert(stype == MethodType.methodType(arrayType, arrayType));
+            if (nargs <= 5) {
+                // invoke target as a spreader also:
+                Object res2 = spreader.invokeWithArguments((Object)res);
+                String res2String = toArrayString(res2);
+                assertEquals(Arrays.toString(args), res2String);
+                // invoke the spreader on a generic Object[] array; check for error
+                try {
+                    Object res3 = spreader.invokeWithArguments((Object)args);
+                    String res3String = toArrayString(res3);
+                    assertTrue(arrayType.getName(), arrayType.isAssignableFrom(Object[].class));
+                    assertEquals(Arrays.toString(args), res3String);
+                } catch (ClassCastException ex) {
+                    assertFalse(arrayType.getName(), arrayType.isAssignableFrom(Object[].class));
+                }
+            }
+            if (nargs == 0) {
+                // invoke spreader on null arglist
+                Object res3 = spreader.invokeWithArguments((Object)null);
+                String res3String = toArrayString(res3);
+                assertEquals(Arrays.toString(args), res3String);
+            }
+        }
+    }
+
+    private static Object[] makeTestArray(Class<?> elemType, int len) {
+        Wrapper elem = null;
+        if (elemType.isPrimitive())
+            elem = Wrapper.forPrimitiveType(elemType);
+        else if (Wrapper.isWrapperType(elemType))
+            elem = Wrapper.forWrapperType(elemType);
+        Object[] args = new Object[len];
+        for (int i = 0; i < len; i++) {
+            Object arg = i * 100;
+            if (elem == null) {
+                if (elemType == String.class)
+                    arg = "#"+arg;
+                arg = elemType.cast(arg);  // just to make sure
+            } else {
+                switch (elem) {
+                    case BOOLEAN: arg = (i % 3 == 0);           break;
+                    case CHAR:    arg = 'a' + i;                break;
+                    case LONG:    arg = (long)i * 1000_000_000; break;
+                    case FLOAT:   arg = (float)i / 100;         break;
+                    case DOUBLE:  arg = (double)i / 1000_000;   break;
+                }
+                arg = elem.cast(arg, elemType);
+            }
+            args[i] = arg;
+        }
+        //System.out.println(elemType.getName()+Arrays.toString(args));
+        return args;
+    }
+
+    private static String toArrayString(Object a) {
+        if (a == null)  return "null";
+        Class<?> elemType = a.getClass().getComponentType();
+        if (elemType == null)  return a.toString();
+        if (elemType.isPrimitive()) {
+            switch (Wrapper.forPrimitiveType(elemType)) {
+                case INT:      return Arrays.toString((int[])a);
+                case BYTE:     return Arrays.toString((byte[])a);
+                case BOOLEAN:  return Arrays.toString((boolean[])a);
+                case SHORT:    return Arrays.toString((short[])a);
+                case CHAR:     return Arrays.toString((char[])a);
+                case FLOAT:    return Arrays.toString((float[])a);
+                case LONG:     return Arrays.toString((long[])a);
+                case DOUBLE:   return Arrays.toString((double[])a);
+            }
+        }
+        return Arrays.toString((Object[])a);
+    }
+
+    @Test
+    public void testVarargsList() throws Throwable {
+        //System.out.println("varargsList");
+        final int MIN = START_ARITY;
+        final int MAX = MAX_ARITY-2;  // 253+1 would cause parameter overflow with 'this' added
+        for (int nargs = MIN; nargs <= MAX; nargs = nextArgCount(nargs, 7, MAX)) {
+            MethodHandle target = ValueConversions.varargsList(nargs);
+            Object[] args = new Object[nargs];
+            for (int i = 0; i < nargs; i++)
+                args[i] = "#"+i;
+            Object res = target.invokeWithArguments(args);
+            assertEquals(Arrays.asList(args), res);
+        }
+    }
+}
--- a/langtools/.hgtags	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/.hgtags	Wed May 18 13:19:32 2011 +0200
@@ -116,3 +116,4 @@
 853b6bb99f9b58eb7cf8211c67d3b6e4f1228a3e jdk7-b139
 258e6654aba25aab91c9ba3b4c53d05bc895a86c jdk7-b140
 90adb5d6adc7d99d27c8b142a31ac8921070274f jdk7-b141
+7476b164194c1814704153e74d5ff7e965c6fdbf jdk7-b142
--- a/langtools/src/share/classes/com/sun/source/tree/SynchronizedTree.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/src/share/classes/com/sun/source/tree/SynchronizedTree.java	Wed May 18 13:19:32 2011 +0200
@@ -31,7 +31,7 @@
  * For example:
  * <pre>
  *   synchronized ( <em>expression</em> )
- *       </em>block</em>
+ *       <em>block</em>
  * </pre>
  *
  * @jls section 14.19
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed May 18 13:19:32 2011 +0200
@@ -1006,7 +1006,6 @@
                 try {
                     data = eval.call();
                 } catch (Exception ex) {
-                    ex.printStackTrace();
                     throw new AssertionError(ex);
                 }
             }
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Wed May 18 13:19:32 2011 +0200
@@ -955,7 +955,9 @@
         if (t.isPrimitive() != s.isPrimitive())
             return allowBoxing && (
                     isConvertible(t, s, warn)
-                    || (allowObjectToPrimitiveCast && isConvertible(s, t, warn)));
+                    || (allowObjectToPrimitiveCast &&
+                        s.isPrimitive() &&
+                        isSubtype(boxedClass(s).type, t)));
         if (warn != warnStack.head) {
             try {
                 warnStack = warnStack.prepend(warn);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed May 18 13:19:32 2011 +0200
@@ -1708,20 +1708,24 @@
             // that we are referring to a superclass instance of the
             // current instance (JLS ???).
             else {
-                localEnv.info.selectSuper = cdef != null;
-                localEnv.info.varArgs = false;
+                //the following code alters some of the fields in the current
+                //AttrContext - hence, the current context must be dup'ed in
+                //order to avoid downstream failures
+                Env<AttrContext> rsEnv = localEnv.dup(tree);
+                rsEnv.info.selectSuper = cdef != null;
+                rsEnv.info.varArgs = false;
                 tree.constructor = rs.resolveConstructor(
-                    tree.pos(), localEnv, clazztype, argtypes, typeargtypes);
+                    tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
                 tree.constructorType = tree.constructor.type.isErroneous() ?
                     syms.errType :
                     checkMethod(clazztype,
                         tree.constructor,
-                        localEnv,
+                        rsEnv,
                         tree.args,
                         argtypes,
                         typeargtypes,
-                        localEnv.info.varArgs);
-                if (localEnv.info.varArgs)
+                        rsEnv.info.varArgs);
+                if (rsEnv.info.varArgs)
                     Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
             }
 
@@ -1779,9 +1783,10 @@
 
                 // Reassign clazztype and recompute constructor.
                 clazztype = cdef.sym.type;
+                boolean useVarargs = tree.varargsElement != null;
                 Symbol sym = rs.resolveConstructor(
                     tree.pos(), localEnv, clazztype, argtypes,
-                    typeargtypes, true, tree.varargsElement != null);
+                    typeargtypes, true, useVarargs);
                 Assert.check(sym.kind < AMBIGUOUS || tree.constructor.type.isErroneous());
                 tree.constructor = sym;
                 if (tree.constructor.kind > ERRONEOUS) {
@@ -1794,7 +1799,7 @@
                             tree.args,
                             argtypes,
                             typeargtypes,
-                            localEnv.info.varArgs);
+                            useVarargs);
                 }
             }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed May 18 13:19:32 2011 +0200
@@ -407,9 +407,7 @@
 
         // for varargs arguments as well
         if (useVarargs) {
-            //note: if applicability check is triggered by most specific test,
-            //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
-            Type elemType = types.elemtypeOrType(varargsFormal);
+            Type elemType = types.elemtype(varargsFormal);
             Type elemUndet = types.subst(elemType, tvars, undetvars);
             while (actuals.nonEmpty()) {
                 Type actual = actuals.head.baseType();
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed May 18 13:19:32 2011 +0200
@@ -458,9 +458,7 @@
             throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
 
         if (useVarargs) {
-            //note: if applicability check is triggered by most specific test,
-            //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
-            Type elt = types.elemtypeOrType(varargsFormal);
+            Type elt = types.elemtype(varargsFormal);
             while (argtypes.nonEmpty()) {
                 if (!types.isConvertible(argtypes.head, elt, warn))
                     throw inapplicableMethodException.setMessage("varargs.argument.mismatch",
@@ -819,10 +817,10 @@
     private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
         noteWarner.clear();
         Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
-        return (instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
-                             allowBoxing, false, noteWarner) != null ||
-                 useVarargs && instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
-                                           allowBoxing, true, noteWarner) != null) &&
+        Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs),
+                types.lowerBoundArgtypes(mtype1), null,
+                allowBoxing, false, noteWarner);
+        return mtype2 != null &&
                 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
     }
     //where
@@ -855,7 +853,7 @@
             //append varargs element type as last synthetic formal
             args.append(types.elemtype(varargsTypeTo));
             Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
-            return new MethodSymbol(to.flags_field, to.name, mtype, to.owner);
+            return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
         } else {
             return to;
         }
--- a/langtools/test/tools/javac/types/BoxingConversionTest.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/test/tools/javac/types/BoxingConversionTest.java	Wed May 18 13:19:32 2011 +0200
@@ -118,7 +118,6 @@
     static final Result T = Result.OK_BOTH;
     static final Result F = Result.FAIL_BOTH;
     static final Result A = Result.OK_ASSIGN_ONLY;
-    static final Result X = Result.FAIL_BOTH.FAIL_BOTH;
 
     Result[][] results1 = {
                    //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean
--- a/langtools/test/tools/javac/types/CastTest.java	Tue May 17 00:56:01 2011 -0700
+++ b/langtools/test/tools/javac/types/CastTest.java	Wed May 18 13:19:32 2011 +0200
@@ -42,12 +42,13 @@
  */
 public class CastTest extends TypeHarness {
 
-    Type[] allTypes;
+    Type[] types_no_boxing;
+    Type[] types_boxing;
 
     static final boolean T = true;
     static final boolean F = false;
 
-    boolean[][] cast_result = {
+    boolean[][] cast_result_no_boxing = {
                 //byte, short, int, long, float, double, char, bool, C, +C, I, T, byte[], short[], int[], long[], float[], double[], char[], bool[], C[], +C[], I[], T[]
     /*byte*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
     /*short*/   { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
@@ -74,6 +75,25 @@
     /*I[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , F   , T  , T },
     /*T[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , T   , T  , T }};
 
+    boolean[][] cast_result_boxing = {
+                   //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean, Object
+    /*byte*/       { T   , T    , T  , T   , T    , T     , T   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T },
+    /*short*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
+    /*int*/        { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
+    /*long*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
+    /*float*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
+    /*double*/     { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
+    /*char*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
+    /*bool*/       { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
+    /*Byte*/       { T   , T    , T  , T   , T    , T     , F   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T  },
+    /*Short*/      { F   , T    , T  , T   , T    , T     , F   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
+    /*Integer*/    { F   , F    , T  , T   , T    , T     , F   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
+    /*Long*/       { F   , F    , F  , T   , T    , T     , F   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
+    /*Float*/      { F   , F    , F  , F   , T    , T     , F   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
+    /*Double*/     { F   , F    , F  , F   , F    , T     , F   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
+    /*Character*/  { F   , F    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
+    /*Boolean*/    { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
+    /*Object*/     { T   , T    , T  , T   , T    , T     , T   , T   , T   , T    , T      , T   , T    , T     , T        , T ,      T  }};
     CastTest() {
         Type[] primitiveTypes = {
             predef.byteType,
@@ -85,6 +105,15 @@
             predef.charType,
             predef.booleanType };
 
+        Type[] boxedTypes = new Type[primitiveTypes.length + 1];
+        for (int i = 0 ; i < primitiveTypes.length ; i++) {
+            boxedTypes[i] = box(primitiveTypes[i]);
+        }
+
+        boxedTypes[primitiveTypes.length] = predef.objectType;
+
+        types_boxing = join(Type.class, primitiveTypes, boxedTypes);
+
         Type[] referenceTypes = {
             fac.Class(),
             fac.Class(FINAL),
@@ -97,17 +126,22 @@
             arrayTypes[idx++] = fac.Array(t);
         }
 
-        allTypes = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
+        types_no_boxing = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
     }
 
-    void test() {
-        for (int i = 0; i < allTypes.length ; i++) {
-            for (int j = 0; j < allTypes.length ; j++) {
-                assertCastable(allTypes[i], allTypes[j], cast_result[i][j]);
+    void test(Type[] all_types, boolean[][] cast_result) {
+        for (int i = 0; i < all_types.length ; i++) {
+            for (int j = 0; j < all_types.length ; j++) {
+                assertCastable(all_types[i], all_types[j], cast_result[i][j]);
             }
         }
     }
 
+    void runTests() {
+        test(types_no_boxing, cast_result_no_boxing);
+        test(types_boxing, cast_result_boxing);
+    }
+
     @SuppressWarnings("unchecked")
     <T> T[] join(Class<T> type, T[]... args) {
         int totalLength = 0;
@@ -124,6 +158,6 @@
     }
 
     public static void main(String[] args) {
-        new CastTest().test();
+        new CastTest().runTests();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/varargs/7042566/T7042566.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7042566
+ * @summary Unambiguous varargs method calls flagged as ambiguous
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.Instruction;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.List;
+
+import java.io.File;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Locale;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class T7042566 {
+
+    VarargsMethod m1;
+    VarargsMethod m2;
+    TypeConfiguration actuals;
+
+    T7042566(TypeConfiguration m1_conf, TypeConfiguration m2_conf, TypeConfiguration actuals) {
+        this.m1 = new VarargsMethod(m1_conf);
+        this.m2 = new VarargsMethod(m2_conf);
+        this.actuals = actuals;
+    }
+
+    void compileAndCheck() throws Exception {
+        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+        JavaSource source = new JavaSource();
+        ErrorChecker ec = new ErrorChecker();
+        JavacTask ct = (JavacTask)tool.getTask(null, fm, ec,
+                null, null, Arrays.asList(source));
+        ct.call();
+        check(source, ec);
+    }
+
+    void check(JavaSource source, ErrorChecker ec) {
+        checkCount++;
+        boolean resolutionError = false;
+        VarargsMethod selectedMethod = null;
+
+        boolean m1_applicable = m1.isApplicable(actuals);
+        boolean m2_applicable = m2.isApplicable(actuals);
+
+        if (!m1_applicable && !m2_applicable) {
+            resolutionError = true;
+        } else if (m1_applicable && m2_applicable) {
+            //most specific
+            boolean m1_moreSpecific = m1.isMoreSpecificThan(m2);
+            boolean m2_moreSpecific = m2.isMoreSpecificThan(m1);
+
+            resolutionError = m1_moreSpecific == m2_moreSpecific;
+            selectedMethod = m1_moreSpecific ? m1 : m2;
+        } else {
+            selectedMethod = m1_applicable ?
+                m1 : m2;
+        }
+
+        if (ec.errorFound != resolutionError) {
+            throw new Error("invalid diagnostics for source:\n" +
+                    source.getCharContent(true) +
+                    "\nExpected resolution error: " + resolutionError +
+                    "\nFound error: " + ec.errorFound +
+                    "\nCompiler diagnostics:\n" + ec.printDiags());
+        } else if (!resolutionError) {
+            verifyBytecode(selectedMethod, source);
+        }
+    }
+
+    void verifyBytecode(VarargsMethod selected, JavaSource source) {
+        bytecodeCheckCount++;
+        File compiledTest = new File("Test.class");
+        try {
+            ClassFile cf = ClassFile.read(compiledTest);
+            Method testMethod = null;
+            for (Method m : cf.methods) {
+                if (m.getName(cf.constant_pool).equals("test")) {
+                    testMethod = m;
+                    break;
+                }
+            }
+            if (testMethod == null) {
+                throw new Error("Test method not found");
+            }
+            Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
+            if (testMethod == null) {
+                throw new Error("Code attribute for test() method not found");
+            }
+
+            for (Instruction i : ea.getInstructions()) {
+                if (i.getMnemonic().equals("invokevirtual")) {
+                    int cp_entry = i.getUnsignedShort(1);
+                    CONSTANT_Methodref_info methRef =
+                            (CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry);
+                    String type = methRef.getNameAndTypeInfo().getType();
+                    String sig = selected.parameterTypes.bytecodeSigStr;
+                    if (!type.contains(sig)) {
+                        throw new Error("Unexpected type method call: " + type + "" +
+                                        "\nfound: " + sig +
+                                        "\n" + source.getCharContent(true));
+                    }
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new Error("error reading " + compiledTest +": " + e);
+        }
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        static final String source_template = "class Test {\n" +
+                "   #V1\n" +
+                "   #V2\n" +
+                "   void test() { m(#E); }\n" +
+                "}";
+
+        String source;
+
+        public JavaSource() {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            source = source_template.replaceAll("#V1", m1.toString()).
+                    replaceAll("#V2", m2.toString()).
+                    replaceAll("#E", actuals.expressionListStr);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    /** global decls ***/
+
+    // Create a single file manager and reuse it for each compile to save time.
+    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
+
+    //statistics
+    static int checkCount = 0;
+    static int bytecodeCheckCount = 0;
+
+    public static void main(String... args) throws Exception {
+        for (TypeConfiguration tconf1 : TypeConfiguration.values()) {
+            for (TypeConfiguration tconf2 : TypeConfiguration.values()) {
+                for (TypeConfiguration tconf3 : TypeConfiguration.values()) {
+                    new T7042566(tconf1, tconf2, tconf3).compileAndCheck();
+                }
+            }
+        }
+
+        System.out.println("Total checks made: " + checkCount);
+        System.out.println("Bytecode checks made: " + bytecodeCheckCount);
+    }
+
+    enum TypeKind {
+        OBJECT("Object", "(Object)null", "Ljava/lang/Object;"),
+        STRING("String", "(String)null", "Ljava/lang/String;");
+
+        String typeString;
+        String valueString;
+        String bytecodeString;
+
+        TypeKind(String typeString, String valueString, String bytecodeString) {
+            this.typeString = typeString;
+            this.valueString = valueString;
+            this.bytecodeString = bytecodeString;
+        }
+
+        boolean isSubtypeOf(TypeKind that) {
+            return that == OBJECT ||
+                    (that == STRING && this == STRING);
+        }
+    }
+
+    enum TypeConfiguration {
+        A(TypeKind.OBJECT),
+        B(TypeKind.STRING),
+        AA(TypeKind.OBJECT, TypeKind.OBJECT),
+        AB(TypeKind.OBJECT, TypeKind.STRING),
+        BA(TypeKind.STRING, TypeKind.OBJECT),
+        BB(TypeKind.STRING, TypeKind.STRING),
+        AAA(TypeKind.OBJECT, TypeKind.OBJECT, TypeKind.OBJECT),
+        AAB(TypeKind.OBJECT, TypeKind.OBJECT, TypeKind.STRING),
+        ABA(TypeKind.OBJECT, TypeKind.STRING, TypeKind.OBJECT),
+        ABB(TypeKind.OBJECT, TypeKind.STRING, TypeKind.STRING),
+        BAA(TypeKind.STRING, TypeKind.OBJECT, TypeKind.OBJECT),
+        BAB(TypeKind.STRING, TypeKind.OBJECT, TypeKind.STRING),
+        BBA(TypeKind.STRING, TypeKind.STRING, TypeKind.OBJECT),
+        BBB(TypeKind.STRING, TypeKind.STRING, TypeKind.STRING);
+
+        List<TypeKind> typeKindList;
+        String expressionListStr;
+        String parameterListStr;
+        String bytecodeSigStr;
+
+        private TypeConfiguration(TypeKind... typeKindList) {
+            this.typeKindList = List.from(typeKindList);
+            expressionListStr = asExpressionList();
+            parameterListStr = asParameterList();
+            bytecodeSigStr = asBytecodeString();
+        }
+
+        private String asExpressionList() {
+            StringBuilder buf = new StringBuilder();
+            String sep = "";
+            for (TypeKind tk : typeKindList) {
+                buf.append(sep);
+                buf.append(tk.valueString);
+                sep = ",";
+            }
+            return buf.toString();
+        }
+
+        private String asParameterList() {
+            StringBuilder buf = new StringBuilder();
+            String sep = "";
+            int count = 0;
+            for (TypeKind arg : typeKindList) {
+                buf.append(sep);
+                buf.append(arg.typeString);
+                if (count == (typeKindList.size() - 1)) {
+                    buf.append("...");
+                }
+                buf.append(" ");
+                buf.append("arg" + count++);
+                sep = ",";
+            }
+            return buf.toString();
+        }
+
+        private String asBytecodeString() {
+            StringBuilder buf = new StringBuilder();
+            int count = 0;
+            for (TypeKind arg : typeKindList) {
+                if (count == (typeKindList.size() - 1)) {
+                    buf.append("[");
+                }
+                buf.append(arg.bytecodeString);
+                count++;
+            }
+            return buf.toString();
+        }
+    }
+
+    static class VarargsMethod {
+        TypeConfiguration parameterTypes;
+
+        public VarargsMethod(TypeConfiguration parameterTypes) {
+            this.parameterTypes = parameterTypes;
+        }
+
+        @Override
+        public String toString() {
+            return "void m( " + parameterTypes.parameterListStr + ") {}";
+        }
+
+        boolean isApplicable(TypeConfiguration that) {
+            List<TypeKind> actuals = that.typeKindList;
+            List<TypeKind> formals = parameterTypes.typeKindList;
+            if ((actuals.size() - formals.size()) < -1)
+                return false; //not enough args
+            for (TypeKind actual : actuals) {
+                if (!actual.isSubtypeOf(formals.head))
+                    return false; //type mismatch
+                formals = formals.tail.isEmpty() ?
+                    formals :
+                    formals.tail;
+            }
+            return true;
+        }
+
+        boolean isMoreSpecificThan(VarargsMethod that) {
+            List<TypeKind> actuals = parameterTypes.typeKindList;
+            List<TypeKind> formals = that.parameterTypes.typeKindList;
+            int checks = 0;
+            int expectedCheck = Math.max(actuals.size(), formals.size());
+            while (checks < expectedCheck) {
+                if (!actuals.head.isSubtypeOf(formals.head))
+                    return false; //type mismatch
+                formals = formals.tail.isEmpty() ?
+                    formals :
+                    formals.tail;
+                actuals = actuals.tail.isEmpty() ?
+                    actuals :
+                    actuals.tail;
+                checks++;
+            }
+            return true;
+        }
+    }
+
+    static class ErrorChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound;
+        List<String> errDiags = List.nil();
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errDiags = errDiags.append(diagnostic.getMessage(Locale.getDefault()));
+                errorFound = true;
+            }
+        }
+
+        String printDiags() {
+            StringBuilder buf = new StringBuilder();
+            for (String s : errDiags) {
+                buf.append(s);
+                buf.append("\n");
+            }
+            return buf.toString();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/varargs/7043922/T7043922.java	Wed May 18 13:19:32 2011 +0200
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7043922
+ * @summary Regression: internal compiler error for nested anonymous inner class featuring varargs constructor
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.List;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Locale;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class T7043922 {
+
+    ClassKind[] classKinds;
+    ConstructorKind[] constructorKinds;
+
+    T7043922(ClassKind[] classKinds, ConstructorKind[] constructorKinds) {
+        this.classKinds = classKinds;
+        this.constructorKinds = constructorKinds;
+    }
+
+    void compileAndCheck() throws Exception {
+        JavaSource source = new JavaSource();
+        ErrorChecker ec = new ErrorChecker();
+        JavacTask ct = (JavacTask)tool.getTask(null, fm, ec,
+                null, null, Arrays.asList(source));
+        ct.analyze();
+        if (ec.errorFound) {
+            throw new Error("invalid diagnostics for source:\n" +
+                    source.getCharContent(true) +
+                    "\nCompiler diagnostics:\n" + ec.printDiags());
+        }
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        static final String source_template = "#C0 A0 { #K0 }\n" +
+                                              "#C1 A1 { #K1 }\n" +
+                                              "#C2 A2 { #K2 }\n" +
+                                              "class D {\n" +
+                                              "   void test() {\n" +
+                                              "      new A0(#V0) {\n" +
+                                              "         void test() {\n" +
+                                              "            new A1(#V1) {\n" +
+                                              "               void test() {\n" +
+                                              "                   new A2(#V2) {};\n" +
+                                              "               }\n" +
+                                              "            };\n" +
+                                              "         }\n" +
+                                              "      };\n" +
+                                              "   }\n" +
+                                              "}\n";
+
+        String source;
+
+        public JavaSource() {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            source = source_template;
+            for (int i = 0; i < 3; i++) {
+                source = source.replaceAll("#C" + i, classKinds[i].classKind).
+                    replaceAll("#K" + i, classKinds[i].getConstructor("A" + i, constructorKinds[i])).
+                    replaceAll("#V" + i, constructorKinds[i].constrArgs);
+            }
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    /** global decls ***/
+
+    enum ConstructorKind {
+        DEFAULT("", ""),
+        FIXED_ARITY("String s", "\"\""),
+        VARIABLE_ARITY("String... ss", "\"\",\"\"");
+
+        String constrParam;
+        String constrArgs;
+
+        private ConstructorKind(String constrParam, String constrArgs) {
+            this.constrParam = constrParam;
+            this.constrArgs = constrArgs;
+        }
+    }
+
+    enum ClassKind {
+        ABSTRACT("abstract class"),
+        CLASS("class"),
+        INTERFACE("interface");
+
+        String classKind;
+
+        private ClassKind(String classKind) {
+            this.classKind = classKind;
+        }
+
+        boolean isConstructorOk(ConstructorKind ck) {
+            return this != INTERFACE ||
+                    ck == ConstructorKind.DEFAULT;
+        }
+
+        String getConstructor(String className, ConstructorKind ck) {
+            return this == INTERFACE ?
+                "" :
+                (className + "(" + ck.constrParam + ") {}");
+        }
+    }
+
+    // Create a single file manager and JavaCompiler tool
+    // and reuse them for each compile to save time.
+    static final StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
+    static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+
+    public static void main(String... args) throws Exception {
+        for (ClassKind classKind1 : ClassKind.values()) {
+            for (ConstructorKind constrKind1 : ConstructorKind.values()) {
+                if (!classKind1.isConstructorOk(constrKind1)) continue;
+                for (ClassKind classKind2 : ClassKind.values()) {
+                    for (ConstructorKind constrKind2 : ConstructorKind.values()) {
+                        if (!classKind2.isConstructorOk(constrKind2)) continue;
+                        for (ClassKind classKind3 : ClassKind.values()) {
+                            for (ConstructorKind constrKind3 : ConstructorKind.values()) {
+                                if (!classKind3.isConstructorOk(constrKind3)) continue;
+                                new T7043922(new ClassKind[] { classKind1, classKind2, classKind3 },
+                                        new ConstructorKind[] { constrKind1, constrKind2, constrKind3 }).compileAndCheck();
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    static class ErrorChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound;
+        List<String> errDiags = List.nil();
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errDiags = errDiags.append(diagnostic.getMessage(Locale.getDefault()));
+                errorFound = true;
+            }
+        }
+
+        String printDiags() {
+            StringBuilder buf = new StringBuilder();
+            for (String s : errDiags) {
+                buf.append(s);
+                buf.append("\n");
+            }
+            return buf.toString();
+        }
+    }
+}
--- a/make/jprt.gmk	Tue May 17 00:56:01 2011 -0700
+++ b/make/jprt.gmk	Wed May 18 13:19:32 2011 +0200
@@ -37,7 +37,7 @@
 JPRT_ARCHIVE_INSTALL_BUNDLE=$(ABS_OUTPUTDIR)/$(DEFAULT_BUILD_FLAVOR)-install-bundle.zip
 
 jprt_build_product:  sanity all_product_build
-	( $(CD) $(OUTPUTDIR)/j2sdk-image && \
+	( $(CD) $(OUTPUTDIR)/$(JDK_IMAGE_DIRNAME) && \
 	  $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
 ifdef HAVE_JPRT_SAVE_BUNDLES
 	( $(CD) $(OUTPUTDIR)/bundles && \
@@ -45,11 +45,11 @@
 endif
 
 jprt_build_fastdebug: fastdebug_build
-	( $(CD) $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-fastdebug/j2sdk-image && \
+	( $(CD) $(OUTPUTDIR)/$(REL_JDK_FASTDEBUG_IMAGE_DIR) && \
 	  $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
 
 jprt_build_debug: debug_build
-	( $(CD) $(OUTPUTDIR)/../$(PLATFORM)-$(ARCH)-debug/j2sdk-image && \
+	( $(CD) $(OUTPUTDIR)/$(REL_JDK_DEBUG_IMAGE_DIR) && \
 	  $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
 
 ################################################################