changeset 3165:0fc9955d603f

Merge
author lana
date Thu, 11 Nov 2010 18:46:02 -0800
parents 4b09cad8528d ecab7eefb8f2
children 809ec4b6eb88
files src/share/classes/java/dyn/JavaMethodHandle.java src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java test/java/nio/channels/AsynchronousDatagramChannel/Basic.java
diffstat 300 files changed, 21147 insertions(+), 7644 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Nov 02 22:15:35 2010 -0700
+++ b/.hgtags	Thu Nov 11 18:46:02 2010 -0800
@@ -91,3 +91,5 @@
 e250cef36ea05e627e7e6f7d75e5e19f529e2ba3 jdk7-b114
 449bad8d67b5808ecf0f927683acc0a5940f8c85 jdk7-b115
 1657ed4e1d86c8aa2028ab5a41f9da1ac4a369f8 jdk7-b116
+3e6726bbf80a4254ecd01051c8ed77ee19325e46 jdk7-b117
+b357910aa04aead2a16b6d6ff395a8df4b51d1dd jdk7-b118
--- a/make/java/java/FILES_java.gmk	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/java/java/FILES_java.gmk	Thu Nov 11 18:46:02 2010 -0800
@@ -413,6 +413,7 @@
     java/io/FilePermission.java \
     java/io/Serializable.java \
     java/io/Externalizable.java \
+    java/io/SerialCallbackContext.java \
 	java/io/Bits.java \
 	java/io/ObjectInput.java \
 	java/io/ObjectInputStream.java \
--- a/make/java/jli/Makefile	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/java/jli/Makefile	Thu Nov 11 18:46:02 2010 -0800
@@ -148,14 +148,9 @@
 #
 ifeq ($(PLATFORM), windows)
 
-STATIC_LIBRARY_DIR = $(OBJDIR)/static
-STATIC_LIBRARY_NAME = $(LIBPREFIX)$(LIBRARY).lib
-STATIC_LIBRARY = $(STATIC_LIBRARY_DIR)/$(STATIC_LIBRARY_NAME)
+STATIC_LIBRARY = $(OBJDIR)/static/$(LIBPREFIX)$(LIBRARY).lib
 
-$(STATIC_LIBRARY_DIR): $(OBJDIR)
-	@$(MKDIR) $(STATIC_LIBRARY_DIR)
-
-$(STATIC_LIBRARY): $(STATIC_LIBRARY_DIR)
+$(STATIC_LIBRARY): $(FILES_o)
 	@$(prep-target)
 	$(LIBEXE) -nologo -out:$@ $(FILES_o)
 
--- a/make/java/nio/FILES_java.gmk	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/java/nio/FILES_java.gmk	Thu Nov 11 18:46:02 2010 -0800
@@ -33,7 +33,6 @@
 	java/nio/channels/AsynchronousByteChannel.java \
 	java/nio/channels/AsynchronousChannel.java \
 	java/nio/channels/AsynchronousChannelGroup.java \
-	java/nio/channels/AsynchronousDatagramChannel.java \
 	java/nio/channels/AsynchronousFileChannel.java \
 	java/nio/channels/AsynchronousServerSocketChannel.java \
 	java/nio/channels/AsynchronousSocketChannel.java \
@@ -207,7 +206,6 @@
 	sun/nio/ch/SelChImpl.java \
 	sun/nio/ch/ServerSocketAdaptor.java \
 	sun/nio/ch/ServerSocketChannelImpl.java \
-	sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java \
         sun/nio/ch/SinkChannelImpl.java \
 	sun/nio/ch/SocketAdaptor.java \
 	sun/nio/ch/SocketChannelImpl.java \
--- a/make/javax/sound/jsoundds/Makefile	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/javax/sound/jsoundds/Makefile	Thu Nov 11 18:46:02 2010 -0800
@@ -53,7 +53,7 @@
 #
 # Extra cc/linker flags.
 #
-LDLIBS += dsound.lib winmm.lib user32.lib
+LDLIBS += dsound.lib winmm.lib user32.lib ole32.lib
 CPPFLAGS += \
 	-DUSE_DAUDIO=TRUE \
 	-I$(SHARE_SRC)/native/com/sun/media/sound \
--- a/make/netbeans/jmx/build.properties	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/netbeans/jmx/build.properties	Thu Nov 11 18:46:02 2010 -0800
@@ -48,8 +48,8 @@
 jar.jmx.sealed				= true
 jar.jmx.spec.title			= JSR 003, 160, 255 - JMX API
 jar.jmx.spec.version			= ${project.spec.version}
-jar.jmx.spec.vendor			= Sun Microsystems, Inc.
-jar.jmx.impl.title			= JSR 003, 160, 255 - OpenJDK 7 JMX API 
+jar.jmx.spec.vendor			= Oracle Corporation
+jar.jmx.impl.title			= JSR 003, 160, 255 - OpenJDK 7 JMX API
 jar.jmx.impl.vendor			= Project OpenJDK
 
 javadoc.options=-J-Xmx256m
--- a/make/sun/javazic/tzdata/VERSION	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/sun/javazic/tzdata/VERSION	Thu Nov 11 18:46:02 2010 -0800
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2010l
+tzdata2010o
--- a/make/sun/javazic/tzdata/asia	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/sun/javazic/tzdata/asia	Thu Nov 11 18:46:02 2010 -0800
@@ -569,8 +569,8 @@
 Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
 Rule	HK	1954	only	-	Oct	31	3:30	0	-
 Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
-Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
-Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
+Rule	HK	1965	1976	-	Apr	Sun>=16	3:30	1:00	S
+Rule	HK	1965	1976	-	Oct	Sun>=16	3:30	0	-
 Rule	HK	1973	only	-	Dec	30	3:30	1:00	S
 Rule	HK	1979	only	-	May	Sun>=8	3:30	1:00	S
 Rule	HK	1979	only	-	Oct	Sun>=16	3:30	0	-
--- a/make/sun/javazic/tzdata/australasia	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/sun/javazic/tzdata/australasia	Thu Nov 11 18:46:02 2010 -0800
@@ -306,13 +306,26 @@
 # http://www.timeanddate.com/news/time/fiji-dst-ends-march-2010.html
 # </a>
 
+# From Alexander Krivenyshev (2010-10-24):
+# According to Radio Fiji and Fiji Times online, Fiji will end DST 3 
+# weeks earlier than expected - on March 6, 2011, not March 27, 2011...
+# Here is confirmation from Government of the Republic of the Fiji Islands, 
+# Ministry of Information (fiji.gov.fj) web site:
+# <a href="http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155">
+# http://www.fiji.gov.fj/index.php?option=com_content&view=article&id=2608:daylight-savings&catid=71:press-releases&Itemid=155
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_fiji04.html">
+# http://www.worldtimezone.com/dst_news/dst_news_fiji04.html
+# </a>
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
 Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
 Rule	Fiji	2009	only	-	Nov	29	2:00	1:00	S
 Rule	Fiji	2010	only	-	Mar	lastSun	3:00	0	-
 Rule	Fiji	2010	only	-	Oct	24	2:00	1:00	S
-Rule	Fiji	2011	only	-	Mar	lastSun 3:00	0	-
+Rule	Fiji	2011	only	-	Mar	Sun>=1	3:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
 			12:00	Fiji	FJ%sT	# Fiji Time
@@ -509,11 +522,21 @@
 # http://www.parliament.gov.ws/documents/acts/Daylight%20Saving%20Act%20%202009%20%28English%29%20-%20Final%207-7-091.pdf
 # </a>
 
+# From Raymond Hughes (2010-10-07):
+# Please see
+# <a href="http://www.mcil.gov.ws">
+# http://www.mcil.gov.ws
+# </a>,
+# the Ministry of Commerce, Industry and Labour (sideframe) "Last Sunday
+# September 2010 (26/09/10) - adjust clocks forward from 12:00 midnight
+# to 01:00am and First Sunday April 2011 (03/04/11) - adjust clocks
+# backwards from 1:00am to 12:00am"
+
 Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
 			-11:26:56 -	LMT	1911
 			-11:30	-	SAMT	1950		# Samoa Time
 			-11:00	-	WST	2010 Sep 26
-			-11:00	1:00	WSDT	2011 Apr 3
+			-11:00	1:00	WSDT	2011 Apr 3 1:00
 			-11:00	-	WST
 
 # Solomon Is
--- a/make/sun/javazic/tzdata/zone.tab	Tue Nov 02 22:15:35 2010 -0700
+++ b/make/sun/javazic/tzdata/zone.tab	Thu Nov 11 18:46:02 2010 -0800
@@ -63,7 +63,7 @@
 AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
 AQ	-6835+07758	Antarctica/Davis	Davis Station, Vestfold Hills
 AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
-AQ	-7824+10654	Antarctica/Vostok	Vostok Station, S Magnetic Pole
+AQ	-7824+10654	Antarctica/Vostok	Vostok Station, Lake Vostok
 AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
 AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
 AQ	-5430+15857	Antarctica/Macquarie	Macquarie Island Station, Macquarie Island
--- a/src/share/bin/java.c	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/bin/java.c	Thu Nov 11 18:46:02 2010 -0800
@@ -355,7 +355,6 @@
 
     JavaVM *vm = 0;
     JNIEnv *env = 0;
-    jstring mainClassName;
     jclass mainClass;
     jmethodID mainID;
     jobjectArray mainArgs;
--- a/src/share/bin/parse_manifest.c	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/bin/parse_manifest.c	Thu Nov 11 18:46:02 2010 -0800
@@ -72,7 +72,7 @@
     if (entry->how == STORED) {
         *(char *)((size_t)in + entry->csize) = '\0';
         if (size_out) {
-            *size_out = entry->csize;
+            *size_out = (int)entry->csize;
         }
         return (in);
     } else if (entry->how == DEFLATED) {
@@ -103,7 +103,7 @@
             return (NULL);
         }
         if (size_out) {
-            *size_out = entry->isize;
+            *size_out = (int)entry->isize;
         }
         return (out);
     } else
@@ -317,7 +317,7 @@
          * manifest.  If so, build the entry record from the data found in
          * the header located and return success.
          */
-        if (CENNAM(p) == JLI_StrLen(file_name) &&
+        if ((size_t)CENNAM(p) == JLI_StrLen(file_name) &&
           memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) {
             if (lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (off_t)0) {
                 free(buffer);
@@ -606,8 +606,5 @@
     }
     free(mp);
     close(fd);
-    if (rc == 0)
-        return (0);
-    else
-        return (-2);
+    return (rc == 0) ? 0 : -2;
 }
--- a/src/share/bin/wildcard.c	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/bin/wildcard.c	Thu Nov 11 18:46:02 2010 -0800
@@ -290,12 +290,12 @@
     char *path;
     char *p;
     for (i = 0, size = 1; i < fl->size; i++)
-        size += JLI_StrLen(fl->files[i]) + 1;
+        size += (int)JLI_StrLen(fl->files[i]) + 1;
 
     path = JLI_MemAlloc(size);
 
     for (i = 0, p = path; i < fl->size; i++) {
-        int len = JLI_StrLen(fl->files[i]);
+        int len = (int)JLI_StrLen(fl->files[i]);
         if (i > 0) *p++ = sep;
         memcpy(p, fl->files[i], len);
         p += len;
@@ -309,7 +309,7 @@
 FileList_split(const char *path, char sep)
 {
     const char *p, *q;
-    int len = JLI_StrLen(path);
+    int len = (int)JLI_StrLen(path);
     int count;
     FileList fl;
     for (count = 1, p = path; p < path + len; p++)
@@ -330,7 +330,7 @@
 static int
 isJarFileName(const char *filename)
 {
-    int len = JLI_StrLen(filename);
+    int len = (int)JLI_StrLen(filename);
     return (len >= 4) &&
         (filename[len - 4] == '.') &&
         (equal(filename + len - 3, "jar") ||
@@ -342,8 +342,8 @@
 static char *
 wildcardConcat(const char *wildcard, const char *basename)
 {
-    int wildlen = JLI_StrLen(wildcard);
-    int baselen = JLI_StrLen(basename);
+    int wildlen = (int)JLI_StrLen(wildcard);
+    int baselen = (int)JLI_StrLen(basename);
     char *filename = (char *) JLI_MemAlloc(wildlen + baselen);
     /* Replace the trailing '*' with basename */
     memcpy(filename, wildcard, wildlen-1);
@@ -369,7 +369,7 @@
 static int
 isWildcard(const char *filename)
 {
-    int len = JLI_StrLen(filename);
+    int len = (int)JLI_StrLen(filename);
     return (len > 0) &&
         (filename[len - 1] == '*') &&
         (len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) &&
--- a/src/share/classes/com/sun/crypto/provider/AESCrypt.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/AESCrypt.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -253,7 +253,8 @@
             for (j = 0; j < 8; j++) {
                 if (AA[i][j] != 0) {
                     AA[i][j] = (byte)
-                        alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255];
+                        alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF])
+                        % 255];
                 }
             }
             for (t = 0; t < 4; t++) {
--- a/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -92,7 +92,8 @@
     }
 
     // core crypt code. OFB style, so works for both encryption and decryption
-    private void crypt(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
+    private void crypt(byte[] in, int inOfs, int inLen, byte[] out,
+            int outOfs) {
         if (is < 0) {
             // doFinal() was called, need to reset the cipher to initial state
             init(lastKey);
--- a/src/share/classes/com/sun/crypto/provider/DESedeCipher.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/DESedeCipher.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,8 +31,8 @@
 import javax.crypto.spec.*;
 
 /**
- * This class implements the DESede algorithm (DES-EDE, tripleDES) in its various
- * modes (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>,
+ * This class implements the DESede algorithm (DES-EDE, tripleDES) in
+ * its various modes (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>,
  * <code>CBC</code>, <code>PCBC</code>) and padding schemes
  * (<code>PKCS5Padding</code>, <code>NoPadding</code>,
  * <code>ISO10126Padding</code>).
--- a/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -190,7 +190,8 @@
             ike.initCause(e);
             throw ike;
         } catch (IOException e) {
-            InvalidKeyException ike = new InvalidKeyException("Error parsing key encoding: " + e.getMessage());
+            InvalidKeyException ike = new InvalidKeyException(
+                "Error parsing key encoding: " + e.getMessage());
             ike.initCause(e);
             throw ike;
         }
@@ -300,7 +301,8 @@
             DerInputStream in = new DerInputStream(this.key);
             this.x = in.getBigInteger();
         } catch (IOException e) {
-            InvalidKeyException ike = new InvalidKeyException("Error parsing key encoding: " + e.getMessage());
+            InvalidKeyException ike = new InvalidKeyException(
+                "Error parsing key encoding: " + e.getMessage());
             ike.initCause(e);
             throw ike;
         }
--- a/src/share/classes/com/sun/crypto/provider/DHPublicKey.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/DHPublicKey.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -180,7 +180,8 @@
             throw new InvalidKeyException("Private-value length too big");
 
         } catch (IOException e) {
-            throw new InvalidKeyException("Error parsing key encoding: " + e.toString());
+            throw new InvalidKeyException(
+                "Error parsing key encoding: " + e.toString());
         }
     }
 
@@ -281,7 +282,8 @@
             DerInputStream in = new DerInputStream(this.key);
             this.y = in.getBigInteger();
         } catch (IOException e) {
-            throw new InvalidKeyException("Error parsing key encoding: " + e.toString());
+            throw new InvalidKeyException(
+                "Error parsing key encoding: " + e.toString());
         }
     }
 
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -764,7 +764,8 @@
                                     cf = (CertificateFactory)cfs.get(certType);
                                 } else {
                                 // create new certificate factory
-                                    cf = CertificateFactory.getInstance(certType);
+                                    cf = CertificateFactory.getInstance(
+                                        certType);
                                 // store the certificate factory so we can
                                 // reuse it later
                                     cfs.put(certType, cf);
@@ -863,8 +864,9 @@
                     dis.readFully(actual);
                     for (int i = 0; i < computed.length; i++) {
                         if (computed[i] != actual[i]) {
-                            throw new IOException("Keystore was tampered with, or "
-                                                  + "password was incorrect");
+                            throw new IOException(
+                                "Keystore was tampered with, or "
+                                + "password was incorrect");
                         }
                     }
                 }
--- a/src/share/classes/com/sun/crypto/provider/OAEPParameters.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/OAEPParameters.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -139,7 +139,8 @@
                 if (!val.getOID().equals((Object) OID_MGF1)) {
                     throw new IOException("Only MGF1 mgf is supported");
                 }
-                AlgorithmId params = AlgorithmId.parse(new DerValue(val.getEncodedParams()));
+                AlgorithmId params = AlgorithmId.parse(
+                    new DerValue(val.getEncodedParams()));
                 String mgfDigestName = convertToStandardName(params.getName());
                 if (mgfDigestName.equals("SHA-1")) {
                     mgfSpec = MGF1ParameterSpec.SHA1;
@@ -150,7 +151,8 @@
                 } else if (mgfDigestName.equals("SHA-512")) {
                     mgfSpec = MGF1ParameterSpec.SHA512;
                 } else {
-                    throw new IOException("Unrecognized message digest algorithm");
+                    throw new IOException(
+                        "Unrecognized message digest algorithm");
                 }
             } else if (data.isContextSpecific((byte) 0x02)) {
                 // pSource algid
--- a/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -121,8 +121,8 @@
         this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
     }
 
-    private static byte[] deriveKey(final Mac prf, final byte[] password, byte[] salt,
-                                    int iterCount, int keyLengthInBit) {
+    private static byte[] deriveKey(final Mac prf, final byte[] password,
+            byte[] salt, int iterCount, int keyLengthInBit) {
         int keyLength = keyLengthInBit/8;
         byte[] key = new byte[keyLength];
         try {
@@ -155,8 +155,9 @@
                     if (this == obj) return true;
                     if (this.getClass() != obj.getClass()) return false;
                     SecretKey sk = (SecretKey)obj;
-                    return prf.getAlgorithm().equalsIgnoreCase(sk.getAlgorithm()) &&
-                            Arrays.equals(password, sk.getEncoded());
+                    return prf.getAlgorithm().equalsIgnoreCase(
+                        sk.getAlgorithm()) &&
+                        Arrays.equals(password, sk.getEncoded());
                 }
             };
             prf.init(macKey);
--- a/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -206,7 +206,8 @@
                 (algo.equalsIgnoreCase("RC2")?"RC2_40":algo), "SunJCE");
         } catch (GeneralSecurityException gse) {
             // should never happen
-            throw new RuntimeException("SunJCE provider is not configured properly");
+            throw new RuntimeException(
+                "SunJCE provider is not configured properly");
         }
         try {
             params.init(pbeSpec);
@@ -316,7 +317,8 @@
             try {
                 paramSpec = params.getParameterSpec(PBEParameterSpec.class);
             } catch (InvalidParameterSpecException ipse) {
-                throw new InvalidAlgorithmParameterException("requires PBE parameters");
+                throw new InvalidAlgorithmParameterException(
+                    "requires PBE parameters");
             }
         }
         implInit(opmode, key, paramSpec, random);
--- a/src/share/classes/com/sun/crypto/provider/SunJCE.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/SunJCE.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -423,15 +423,31 @@
 
                 /*
                  * SSL/TLS mechanisms
+                 *
+                 * These are strictly internal implementations and may
+                 * be changed at any time.  These names were chosen
+                 * because PKCS11/SunPKCS11 does not yet have TLS1.2
+                 * mechanisms, and it will cause calls to come here.
                  */
                 put("KeyGenerator.SunTlsPrf",
-                        "com.sun.crypto.provider.TlsPrfGenerator");
+                        "com.sun.crypto.provider.TlsPrfGenerator$V10");
+                put("KeyGenerator.SunTls12Prf",
+                        "com.sun.crypto.provider.TlsPrfGenerator$V12");
+
+                put("KeyGenerator.SunTlsMasterSecret",
+                    "com.sun.crypto.provider.TlsMasterSecretGenerator");
+                put("Alg.Alias.KeyGenerator.SunTls12MasterSecret",
+                    "SunTlsMasterSecret");
+
+                put("KeyGenerator.SunTlsKeyMaterial",
+                    "com.sun.crypto.provider.TlsKeyMaterialGenerator");
+                put("Alg.Alias.KeyGenerator.SunTls12KeyMaterial",
+                    "SunTlsKeyMaterial");
+
                 put("KeyGenerator.SunTlsRsaPremasterSecret",
-                        "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator");
-                put("KeyGenerator.SunTlsMasterSecret",
-                        "com.sun.crypto.provider.TlsMasterSecretGenerator");
-                put("KeyGenerator.SunTlsKeyMaterial",
-                        "com.sun.crypto.provider.TlsKeyMaterialGenerator");
+                    "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator");
+                put("Alg.Alias.KeyGenerator.SunTls12RsaPremasterSecret",
+                    "SunTlsRsaPremasterSecret");
 
                 return null;
             }
--- a/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,12 +65,14 @@
         }
         this.spec = (TlsKeyMaterialParameterSpec)params;
         if ("RAW".equals(spec.getMasterSecret().getFormat()) == false) {
-            throw new InvalidAlgorithmParameterException("Key format must be RAW");
+            throw new InvalidAlgorithmParameterException(
+                "Key format must be RAW");
         }
-        protocolVersion = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-        if ((protocolVersion < 0x0300) || (protocolVersion > 0x0302)) {
-            throw new InvalidAlgorithmParameterException
-                ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported");
+        protocolVersion = (spec.getMajorVersion() << 8)
+            | spec.getMinorVersion();
+        if ((protocolVersion < 0x0300) || (protocolVersion > 0x0303)) {
+            throw new InvalidAlgorithmParameterException(
+                "Only SSL 3.0, TLS 1.0/1.1/1.2 supported");
         }
     }
 
@@ -80,8 +82,8 @@
 
     protected SecretKey engineGenerateKey() {
         if (spec == null) {
-            throw new IllegalStateException
-                ("TlsKeyMaterialGenerator must be initialized");
+            throw new IllegalStateException(
+                "TlsKeyMaterialGenerator must be initialized");
         }
         try {
             return engineGenerateKey0();
@@ -99,8 +101,8 @@
         SecretKey clientMacKey = null;
         SecretKey serverMacKey = null;
         SecretKey clientCipherKey = null;
+        SecretKey serverCipherKey = null;
         IvParameterSpec clientIv = null;
-        SecretKey serverCipherKey = null;
         IvParameterSpec serverIv = null;
 
         int macLength = spec.getMacKeyLength();
@@ -109,21 +111,33 @@
         int keyLength = spec.getCipherKeyLength();
         int ivLength = spec.getIvLength();
 
-        int keyBlockLen = macLength + keyLength + (isExportable ? 0 : ivLength);
+        int keyBlockLen = macLength + keyLength
+            + (isExportable ? 0 : ivLength);
         keyBlockLen <<= 1;
         byte[] keyBlock = new byte[keyBlockLen];
 
-        MessageDigest md5 = MessageDigest.getInstance("MD5");
-        MessageDigest sha = MessageDigest.getInstance("SHA1");
+        // These may be used again later for exportable suite calculations.
+        MessageDigest md5 = null;
+        MessageDigest sha = null;
 
         // generate key block
-        if (protocolVersion >= 0x0301) {
-            // TLS
+        if (protocolVersion >= 0x0303) {
+            // TLS 1.2
             byte[] seed = concat(serverRandom, clientRandom);
-            keyBlock = doPRF(masterSecret, LABEL_KEY_EXPANSION, seed,
+            keyBlock = doTLS12PRF(masterSecret, LABEL_KEY_EXPANSION, seed,
+                        keyBlockLen, spec.getPRFHashAlg(),
+                        spec.getPRFHashLength(), spec.getPRFBlockSize());
+        } else if (protocolVersion >= 0x0301) {
+            // TLS 1.0/1.1
+            md5 = MessageDigest.getInstance("MD5");
+            sha = MessageDigest.getInstance("SHA1");
+            byte[] seed = concat(serverRandom, clientRandom);
+            keyBlock = doTLS10PRF(masterSecret, LABEL_KEY_EXPANSION, seed,
                         keyBlockLen, md5, sha);
         } else {
             // SSL
+            md5 = MessageDigest.getInstance("MD5");
+            sha = MessageDigest.getInstance("SHA1");
             keyBlock = new byte[keyBlockLen];
 
             byte[] tmp = new byte[20];
@@ -169,6 +183,7 @@
 
         String alg = spec.getCipherAlgorithm();
 
+        // cipher keys
         byte[] clientKeyBytes = new byte[keyLength];
         System.arraycopy(keyBlock, ofs, clientKeyBytes, 0, keyLength);
         ofs += keyLength;
@@ -182,6 +197,7 @@
             clientCipherKey = new SecretKeySpec(clientKeyBytes, alg);
             serverCipherKey = new SecretKeySpec(serverKeyBytes, alg);
 
+            // IV keys if needed.
             if (ivLength != 0) {
                 tmp = new byte[ivLength];
 
@@ -194,21 +210,28 @@
                 serverIv = new IvParameterSpec(tmp);
             }
         } else {
+            // if exportable suites, calculate the alternate
             // cipher key expansion and IV generation
-            if (protocolVersion >= 0x0301) {
+            if (protocolVersion >= 0x0302) {
+                // TLS 1.1+
+                throw new RuntimeException(
+                    "Internal Error:  TLS 1.1+ should not be negotiating" +
+                    "exportable ciphersuites");
+            } else if (protocolVersion == 0x0301) {
+                // TLS 1.0
                 byte[] seed = concat(clientRandom, serverRandom);
 
-                tmp = doPRF(clientKeyBytes, LABEL_CLIENT_WRITE_KEY, seed,
+                tmp = doTLS10PRF(clientKeyBytes, LABEL_CLIENT_WRITE_KEY, seed,
                             expandedKeyLength, md5, sha);
                 clientCipherKey = new SecretKeySpec(tmp, alg);
 
-                tmp = doPRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
+                tmp = doTLS10PRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
                             expandedKeyLength, md5, sha);
                 serverCipherKey = new SecretKeySpec(tmp, alg);
 
                 if (ivLength != 0) {
                     tmp = new byte[ivLength];
-                    byte[] block = doPRF(null, LABEL_IV_BLOCK, seed,
+                    byte[] block = doTLS10PRF(null, LABEL_IV_BLOCK, seed,
                                 ivLength << 1, md5, sha);
                     System.arraycopy(block, 0, tmp, 0, ivLength);
                     clientIv = new IvParameterSpec(tmp);
@@ -216,6 +239,7 @@
                     serverIv = new IvParameterSpec(tmp);
                 }
             } else {
+                // SSLv3
                 tmp = new byte[expandedKeyLength];
 
                 md5.update(clientKeyBytes);
--- a/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,12 +64,14 @@
         }
         this.spec = (TlsMasterSecretParameterSpec)params;
         if ("RAW".equals(spec.getPremasterSecret().getFormat()) == false) {
-            throw new InvalidAlgorithmParameterException("Key format must be RAW");
+            throw new InvalidAlgorithmParameterException(
+                "Key format must be RAW");
         }
-        protocolVersion = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-        if ((protocolVersion < 0x0300) || (protocolVersion > 0x0302)) {
-            throw new InvalidAlgorithmParameterException
-                ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported");
+        protocolVersion = (spec.getMajorVersion() << 8)
+            | spec.getMinorVersion();
+        if ((protocolVersion < 0x0300) || (protocolVersion > 0x0303)) {
+            throw new InvalidAlgorithmParameterException(
+                "Only SSL 3.0, TLS 1.0/1.1/1.2 supported");
         }
     }
 
@@ -79,8 +81,8 @@
 
     protected SecretKey engineGenerateKey() {
         if (spec == null) {
-            throw new IllegalStateException
-                ("TlsMasterSecretGenerator must be initialized");
+            throw new IllegalStateException(
+                "TlsMasterSecretGenerator must be initialized");
         }
         SecretKey premasterKey = spec.getPremasterSecret();
         byte[] premaster = premasterKey.getEncoded();
@@ -103,7 +105,11 @@
 
             if (protocolVersion >= 0x0301) {
                 byte[] seed = concat(clientRandom, serverRandom);
-                master = doPRF(premaster, LABEL_MASTER_SECRET, seed, 48);
+                master = ((protocolVersion >= 0x0303) ?
+                    doTLS12PRF(premaster, LABEL_MASTER_SECRET, seed, 48,
+                        spec.getPRFHashAlg(), spec.getPRFHashLength(),
+                        spec.getPRFBlockSize()) :
+                    doTLS10PRF(premaster, LABEL_MASTER_SECRET, seed, 48));
             } else {
                 master = new byte[48];
                 MessageDigest md5 = MessageDigest.getInstance("MD5");
@@ -124,7 +130,8 @@
 
             }
 
-            return new TlsMasterSecretKey(master, premasterMajor, premasterMinor);
+            return new TlsMasterSecretKey(master, premasterMajor,
+                premasterMinor);
         } catch (NoSuchAlgorithmException e) {
             throw new ProviderException(e);
         } catch (DigestException e) {
--- a/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,11 +37,15 @@
 
 /**
  * KeyGenerator implementation for the TLS PRF function.
+ * <p>
+ * This class duplicates the HMAC functionality (RFC 2104) with
+ * performance optimizations (e.g. XOR'ing keys with padding doesn't
+ * need to be redone for each HMAC operation).
  *
  * @author  Andreas Sterbenz
  * @since   1.6
  */
-public final class TlsPrfGenerator extends KeyGeneratorSpi {
+abstract class TlsPrfGenerator extends KeyGeneratorSpi {
 
     // magic constants and utility functions, also used by other files
     // in this package
@@ -69,8 +73,10 @@
      * TLS HMAC "inner" and "outer" padding.  This isn't a function
      * of the digest algorithm.
      */
-    private static final byte[] HMAC_ipad = genPad((byte)0x36, 64);
-    private static final byte[] HMAC_opad = genPad((byte)0x5c, 64);
+    private static final byte[] HMAC_ipad64  = genPad((byte)0x36, 64);
+    private static final byte[] HMAC_ipad128 = genPad((byte)0x36, 128);
+    private static final byte[] HMAC_opad64  = genPad((byte)0x5c, 64);
+    private static final byte[] HMAC_opad128 = genPad((byte)0x5c, 128);
 
     // SSL3 magic mix constants ("A", "BB", "CCC", ...)
     final static byte[][] SSL3_CONST = genConst();
@@ -123,8 +129,8 @@
         this.spec = (TlsPrfParameterSpec)params;
         SecretKey key = spec.getSecret();
         if ((key != null) && ("RAW".equals(key.getFormat()) == false)) {
-            throw new InvalidAlgorithmParameterException
-                ("Key encoding format must be RAW");
+            throw new InvalidAlgorithmParameterException(
+                "Key encoding format must be RAW");
         }
     }
 
@@ -132,17 +138,21 @@
         throw new InvalidParameterException(MSG);
     }
 
-    protected SecretKey engineGenerateKey() {
+    SecretKey engineGenerateKey0(boolean tls12) {
         if (spec == null) {
-            throw new IllegalStateException
-                ("TlsPrfGenerator must be initialized");
+            throw new IllegalStateException(
+                "TlsPrfGenerator must be initialized");
         }
         SecretKey key = spec.getSecret();
         byte[] secret = (key == null) ? null : key.getEncoded();
         try {
             byte[] labelBytes = spec.getLabel().getBytes("UTF8");
             int n = spec.getOutputLength();
-            byte[] prfBytes = doPRF(secret, labelBytes, spec.getSeed(), n);
+            byte[] prfBytes = (tls12 ?
+                doTLS12PRF(secret, labelBytes, spec.getSeed(), n,
+                    spec.getPRFHashAlg(), spec.getPRFHashLength(),
+                    spec.getPRFBlockSize()) :
+                doTLS10PRF(secret, labelBytes, spec.getSeed(), n));
             return new SecretKeySpec(prfBytes, "TlsPrf");
         } catch (GeneralSecurityException e) {
             throw new ProviderException("Could not generate PRF", e);
@@ -151,16 +161,67 @@
         }
     }
 
-    static final byte[] doPRF(byte[] secret, byte[] labelBytes, byte[] seed,
-            int outputLength) throws NoSuchAlgorithmException, DigestException {
+    static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes,
+            byte[] seed, int outputLength,
+            String prfHash, int prfHashLength, int prfBlockSize)
+            throws NoSuchAlgorithmException, DigestException {
+        if (prfHash == null) {
+            throw new NoSuchAlgorithmException("Unspecified PRF algorithm");
+        }
+        MessageDigest prfMD = MessageDigest.getInstance(prfHash);
+        return doTLS12PRF(secret, labelBytes, seed, outputLength,
+            prfMD, prfHashLength, prfBlockSize);
+    }
+
+    static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes,
+            byte[] seed, int outputLength,
+            MessageDigest mdPRF, int mdPRFLen, int mdPRFBlockSize)
+            throws DigestException {
+
+        if (secret == null) {
+            secret = B0;
+        }
+
+        // If we have a long secret, digest it first.
+        if (secret.length > mdPRFBlockSize) {
+            secret = mdPRF.digest(secret);
+        }
+
+        byte[] output = new byte[outputLength];
+        byte [] ipad;
+        byte [] opad;
+
+        switch (mdPRFBlockSize) {
+        case 64:
+            ipad = HMAC_ipad64.clone();
+            opad = HMAC_opad64.clone();
+            break;
+        case 128:
+            ipad = HMAC_ipad128.clone();
+            opad = HMAC_opad128.clone();
+            break;
+        default:
+            throw new DigestException("Unexpected block size.");
+        }
+
+        // P_HASH(Secret, label + seed)
+        expand(mdPRF, mdPRFLen, secret, 0, secret.length, labelBytes,
+            seed, output, ipad, opad);
+
+        return output;
+    }
+
+    static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes,
+            byte[] seed, int outputLength) throws NoSuchAlgorithmException,
+            DigestException {
         MessageDigest md5 = MessageDigest.getInstance("MD5");
         MessageDigest sha = MessageDigest.getInstance("SHA1");
-        return doPRF(secret, labelBytes, seed, outputLength, md5, sha);
+        return doTLS10PRF(secret, labelBytes, seed, outputLength, md5, sha);
     }
 
-    static final byte[] doPRF(byte[] secret, byte[] labelBytes, byte[] seed,
-            int outputLength, MessageDigest md5, MessageDigest sha)
-            throws DigestException {
+    static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes,
+            byte[] seed, int outputLength, MessageDigest md5,
+            MessageDigest sha) throws DigestException {
         /*
          * Split the secret into two halves S1 and S2 of same length.
          * S1 is taken from the first half of the secret, S2 from the
@@ -183,10 +244,12 @@
         byte[] output = new byte[outputLength];
 
         // P_MD5(S1, label + seed)
-        expand(md5, 16, secret, 0, seclen, labelBytes, seed, output);
+        expand(md5, 16, secret, 0, seclen, labelBytes, seed, output,
+            HMAC_ipad64.clone(), HMAC_opad64.clone());
 
         // P_SHA-1(S2, label + seed)
-        expand(sha, 20, secret, off, seclen, labelBytes, seed, output);
+        expand(sha, 20, secret, off, seclen, labelBytes, seed, output,
+            HMAC_ipad64.clone(), HMAC_opad64.clone());
 
         return output;
     }
@@ -201,16 +264,13 @@
      * @param seed the seed
      * @param output the output array
      */
-    private static final void expand(MessageDigest digest, int hmacSize,
+    private static void expand(MessageDigest digest, int hmacSize,
             byte[] secret, int secOff, int secLen, byte[] label, byte[] seed,
-            byte[] output) throws DigestException {
+            byte[] output, byte[] pad1, byte[] pad2) throws DigestException {
         /*
          * modify the padding used, by XORing the key into our copy of that
          * padding.  That's to avoid doing that for each HMAC computation.
          */
-        byte[] pad1 = HMAC_ipad.clone();
-        byte[] pad2 = HMAC_opad.clone();
-
         for (int i = 0; i < secLen; i++) {
             pad1[i] ^= secret[i + secOff];
             pad2[i] ^= secret[i + secOff];
@@ -275,7 +335,34 @@
             }
             remaining -= k;
         }
-
     }
 
+    /**
+     * A KeyGenerator implementation that supports TLS 1.2.
+     * <p>
+     * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the PRF
+     * calculations.  As of 2010, there is no PKCS11-level support for TLS
+     * 1.2 PRF calculations, and no known OS's have an internal variant
+     * we could use.  Therefore for TLS 1.2, we are updating JSSE to request
+     * a different provider algorithm:  "SunTls12Prf".  If we reused the
+     * name "SunTlsPrf", the PKCS11 provider would need be updated to
+     * fail correctly when presented with the wrong version number
+     * (via Provider.Service.supportsParameters()), and add the
+     * appropriate supportsParamters() checks into KeyGenerators (not
+     * currently there).
+     */
+    static public class V12 extends TlsPrfGenerator {
+        protected SecretKey engineGenerateKey() {
+            return engineGenerateKey0(true);
+        }
+    }
+
+    /**
+     * A KeyGenerator implementation that supports TLS 1.0/1.1.
+     */
+    static public class V10 extends TlsPrfGenerator {
+        protected SecretKey engineGenerateKey() {
+            return engineGenerateKey0(false);
+        }
+    }
 }
--- a/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,8 +69,8 @@
 
     protected SecretKey engineGenerateKey() {
         if (spec == null) {
-            throw new IllegalStateException
-                    ("TlsRsaPremasterSecretGenerator must be initialized");
+            throw new IllegalStateException(
+                "TlsRsaPremasterSecretGenerator must be initialized");
         }
         if (random == null) {
             random = new SecureRandom();
--- a/src/share/classes/com/sun/jmx/defaults/ServiceName.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/jmx/defaults/ServiceName.java	Thu Nov 11 18:46:02 2010 -0800
@@ -76,9 +76,9 @@
     /**
      * The vendor of the JMX specification implemented by this product.
      * <BR>
-     * The value is <CODE>Sun Microsystems</CODE>.
+     * The value is <CODE>Oracle Corporation</CODE>.
      */
-    public static final String JMX_SPEC_VENDOR = "Sun Microsystems";
+    public static final String JMX_SPEC_VENDOR = "Oracle Corporation";
 
     /**
      * The name of this product implementing the  JMX specification.
@@ -91,7 +91,7 @@
      * The name of the vendor of this product implementing the
      * JMX specification.
      * <BR>
-     * The value is <CODE>Sun Microsystems</CODE>.
+     * The value is <CODE>Oracle Corporation</CODE>.
      */
-    public static final String JMX_IMPL_VENDOR = "Sun Microsystems";
+    public static final String JMX_IMPL_VENDOR = "Oracle Corporation";
 }
--- a/src/share/classes/com/sun/jmx/snmp/ServiceName.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/jmx/snmp/ServiceName.java	Thu Nov 11 18:46:02 2010 -0800
@@ -27,7 +27,7 @@
 
 /**
  * Used for storing default values used by SNMP Runtime services.
- * <p><b>This API is a Sun Microsystems internal API  and is subject
+ * <p><b>This API is an Oracle Corporation internal API  and is subject
  * to change without notice.</b></p>
  */
 public class ServiceName {
@@ -144,16 +144,16 @@
     /**
      * The vendor of the JMX specification implemented by this product.
      * <BR>
-     * The value is <CODE>Sun Microsystems</CODE>.
+     * The value is <CODE>Oracle Corporation</CODE>.
      */
-    public static final String JMX_SPEC_VENDOR = "Sun Microsystems";
+    public static final String JMX_SPEC_VENDOR = "Oracle Corporation";
 
     /**
      * The name of the vendor of this product implementing the  JMX specification.
      * <BR>
-     * The value is <CODE>Sun Microsystems</CODE>.
+     * The value is <CODE>Oracle Corporation</CODE>.
      */
-    public static final String JMX_IMPL_VENDOR = "Sun Microsystems";
+    public static final String JMX_IMPL_VENDOR = "Oracle Corporation";
 
     /**
       * The build number of the current product version, of the form <CODE>rXX</CODE>.
--- a/src/share/classes/com/sun/management/package.html	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/com/sun/management/package.html	Thu Nov 11 18:46:02 2010 -0800
@@ -30,7 +30,7 @@
 </head>
 <body bgcolor="white">
 
-This package contains Sun Microsystem's platform extension to
+This package contains Oracle Corporation's platform extension to
 the implementation of the
 <a href="{@docRoot}/../../../../api/java/lang/management/package-summary.html">
 java.lang.management</a> API and also defines the management
--- a/src/share/classes/java/awt/BasicStroke.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/BasicStroke.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 
 package java.awt;
 
+import java.beans.ConstructorProperties;
+
 /**
  * The <code>BasicStroke</code> class defines a basic set of rendering
  * attributes for the outlines of graphics primitives, which are rendered
@@ -183,6 +185,7 @@
      *         <code>dash</code> is zero
      * @throws IllegalArgumentException if dash lengths are all zero.
      */
+    @ConstructorProperties({ "lineWidth", "endCap", "lineJoin", "miterLimit", "dashArray", "dashPhase" })
     public BasicStroke(float width, int cap, int join, float miterlimit,
                        float dash[], float dash_phase) {
         if (width < 0.0f) {
--- a/src/share/classes/java/awt/GradientPaint.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/GradientPaint.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import java.awt.geom.Rectangle2D;
 import java.awt.geom.AffineTransform;
 import java.awt.image.ColorModel;
+import java.beans.ConstructorProperties;
 
 /**
  * The <code>GradientPaint</code> class provides a way to fill
@@ -166,6 +167,7 @@
      * @throws NullPointerException if either one of colors or points
      * is null
      */
+    @ConstructorProperties({ "point1", "color1", "point2", "color2", "cyclic" })
     public GradientPaint(Point2D pt1,
                          Color color1,
                          Point2D pt2,
--- a/src/share/classes/java/awt/GridBagConstraints.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/GridBagConstraints.java	Thu Nov 11 18:46:02 2010 -0800
@@ -126,7 +126,7 @@
     /**
      * Place the component centered along the edge of its display area
      * associated with the start of a page for the current
-     * <code>ComponentOrienation</code>.  Equal to NORTH for horizontal
+     * {@code ComponentOrientation}.  Equal to NORTH for horizontal
      * orientations.
      */
     public static final int PAGE_START = 19;
@@ -134,7 +134,7 @@
     /**
      * Place the component centered along the edge of its display area
      * associated with the end of a page for the current
-     * <code>ComponentOrienation</code>.  Equal to SOUTH for horizontal
+     * {@code ComponentOrientation}.  Equal to SOUTH for horizontal
      * orientations.
      */
     public static final int PAGE_END = 20;
@@ -142,7 +142,7 @@
     /**
      * Place the component centered along the edge of its display area where
      * lines of text would normally begin for the current
-     * <code>ComponentOrienation</code>.  Equal to WEST for horizontal,
+     * {@code ComponentOrientation}.  Equal to WEST for horizontal,
      * left-to-right orientations and EAST for horizontal, right-to-left
      * orientations.
      */
@@ -151,7 +151,7 @@
     /**
      * Place the component centered along the edge of its display area where
      * lines of text would normally end for the current
-     * <code>ComponentOrienation</code>.  Equal to EAST for horizontal,
+     * {@code ComponentOrientation}.  Equal to EAST for horizontal,
      * left-to-right orientations and WEST for horizontal, right-to-left
      * orientations.
      */
@@ -160,7 +160,7 @@
     /**
      * Place the component in the corner of its display area where
      * the first line of text on a page would normally begin for the current
-     * <code>ComponentOrienation</code>.  Equal to NORTHWEST for horizontal,
+     * {@code ComponentOrientation}.  Equal to NORTHWEST for horizontal,
      * left-to-right orientations and NORTHEAST for horizontal, right-to-left
      * orientations.
      */
@@ -169,7 +169,7 @@
     /**
      * Place the component in the corner of its display area where
      * the first line of text on a page would normally end for the current
-     * <code>ComponentOrienation</code>.  Equal to NORTHEAST for horizontal,
+     * {@code ComponentOrientation}.  Equal to NORTHEAST for horizontal,
      * left-to-right orientations and NORTHWEST for horizontal, right-to-left
      * orientations.
      */
@@ -178,7 +178,7 @@
     /**
      * Place the component in the corner of its display area where
      * the last line of text on a page would normally start for the current
-     * <code>ComponentOrienation</code>.  Equal to SOUTHWEST for horizontal,
+     * {@code ComponentOrientation}.  Equal to SOUTHWEST for horizontal,
      * left-to-right orientations and SOUTHEAST for horizontal, right-to-left
      * orientations.
      */
@@ -187,7 +187,7 @@
     /**
      * Place the component in the corner of its display area where
      * the last line of text on a page would normally end for the current
-     * <code>ComponentOrienation</code>.  Equal to SOUTHEAST for horizontal,
+     * {@code ComponentOrientation}.  Equal to SOUTHEAST for horizontal,
      * left-to-right orientations and SOUTHWEST for horizontal, right-to-left
      * orientations.
      */
@@ -437,7 +437,7 @@
      * <code>LINE_START</code>, <code>LINE_END</code>,
      * <code>FIRST_LINE_START</code>, <code>FIRST_LINE_END</code>,
      * <code>LAST_LINE_START</code> and <code>LAST_LINE_END</code>.  The
-     * baseline relvative values are:
+     * baseline relative values are:
      * <code>BASELINE</code>, <code>BASELINE_LEADING</code>,
      * <code>BASELINE_TRAILING</code>,
      * <code>ABOVE_BASELINE</code>, <code>ABOVE_BASELINE_LEADING</code>,
--- a/src/share/classes/java/awt/LinearGradientPaint.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/LinearGradientPaint.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,10 @@
 package java.awt;
 
 import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.ColorModel;
+import java.beans.ConstructorProperties;
 
 /**
  * The {@code LinearGradientPaint} class provides a way to fill
@@ -271,6 +271,7 @@
      * or a {@code fractions} value is less than 0.0 or greater than 1.0,
      * or the {@code fractions} are not provided in strictly increasing order
      */
+    @ConstructorProperties({ "startPoint", "endPoint", "fractions", "colors", "cycleMethod", "colorSpace", "transform" })
     public LinearGradientPaint(Point2D start, Point2D end,
                                float[] fractions, Color[] colors,
                                CycleMethod cycleMethod,
--- a/src/share/classes/java/awt/RadialGradientPaint.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/RadialGradientPaint.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.ColorModel;
+import java.beans.ConstructorProperties;
 
 /**
  * The {@code RadialGradientPaint} class provides a way to fill a shape with
@@ -428,6 +429,7 @@
      * or a {@code fractions} value is less than 0.0 or greater than 1.0,
      * or the {@code fractions} are not provided in strictly increasing order
      */
+    @ConstructorProperties({ "centerPoint", "radius", "focusPoint", "fractions", "colors", "cycleMethod", "colorSpace", "transform" })
     public RadialGradientPaint(Point2D center,
                                float radius,
                                Point2D focus,
--- a/src/share/classes/java/awt/Scrollbar.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/Scrollbar.java	Thu Nov 11 18:46:02 2010 -0800
@@ -213,7 +213,8 @@
      * The size of the <code>Scrollbar</code>'s bubble.
      * When a scroll bar is used to select a range of values,
      * the visibleAmount represents the size of this range.
-     * This is visually indicated by the size of the bubble.
+     * Depending on platform, this may be visually indicated
+     * by the size of the bubble.
      *
      * @serial
      * @see #getVisibleAmount
@@ -637,6 +638,8 @@
      * bubble (also called a thumb or scroll box), usually gives a
      * visual representation of the relationship of the visible
      * amount to the range of the scroll bar.
+     * Note that depending on platform, the value of the visible amount property
+     * may not be visually indicated by the size of the bubble.
      * <p>
      * The scroll bar's bubble may not be displayed when it is not
      * moveable (e.g. when it takes up the entire length of the
@@ -670,6 +673,8 @@
      * bubble (also called a thumb or scroll box), usually gives a
      * visual representation of the relationship of the visible
      * amount to the range of the scroll bar.
+     * Note that depending on platform, the value of the visible amount property
+     * may not be visually indicated by the size of the bubble.
      * <p>
      * The scroll bar's bubble may not be displayed when it is not
      * moveable (e.g. when it takes up the entire length of the
--- a/src/share/classes/java/awt/Toolkit.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/Toolkit.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1831,7 +1831,11 @@
             desktopProperties.put(name, newValue);
         }
 
-        desktopPropsSupport.firePropertyChange(name, oldValue, newValue);
+        // Don't fire change event if old and new values are null.
+        // It helps to avoid recursive resending of WM_THEMECHANGED
+        if (oldValue != null || newValue != null) {
+            desktopPropsSupport.firePropertyChange(name, oldValue, newValue);
+        }
     }
 
     /**
--- a/src/share/classes/java/awt/geom/AffineTransform.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/awt/geom/AffineTransform.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package java.awt.geom;
 
 import java.awt.Shape;
+import java.beans.ConstructorProperties;
 
 /**
  * The <code>AffineTransform</code> class represents a 2D affine transform
@@ -508,6 +509,7 @@
      * @param m12 the Y coordinate translation element of the 3x3 matrix
      * @since 1.2
      */
+    @ConstructorProperties({ "scaleX", "shearY", "shearX", "scaleY", "translateX", "translateY" })
     public AffineTransform(float m00, float m10,
                            float m01, float m11,
                            float m02, float m12) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/dyn/BootstrapMethod.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.dyn;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotation on InvokeDynamic method calls which requests the JVM to use a specific
+ * <a href="package-summary.html#bsm">bootstrap method</a>
+ * to link the call.  This annotation is not retained as such in the class file,
+ * but is transformed into a constant-pool entry for the invokedynamic instruction which
+ * specifies the desired bootstrap method.
+ * <p>
+ * If only the <code>value</code> is given, it must name a subclass of {@link CallSite}
+ * with a constructor which accepts a class, string, and method type.
+ * If the <code>value</code> and <code>name</code> are both given, there must be
+ * a static method in the given class of the given name which accepts a class, string,
+ * and method type, and returns a reference coercible to {@link CallSite}.
+ * <p>
+ * This annotation can be placed either on the return type of a single {@link InvokeDynamic}
+ * call (see examples) or else it can be placed on an enclosing class or method, where it
+ * determines a default bootstrap method for any {@link InvokeDynamic} calls which are not
+ * specifically annotated with a bootstrap method.
+ * Every {@link InvokeDynamic} call must be given a bootstrap method.
+ * <p>
+ * Examples:
+<blockquote><pre>
+&#064;BootstrapMethod(value=MyLanguageRuntime.class, name="bootstrapDynamic")
+String x = (String) InvokeDynamic.greet();
+//BSM => MyLanguageRuntime.bootstrapDynamic(Here.class, "greet", methodType(String.class))
+&#064;BootstrapMethod(MyCallSite.class)
+void example() throws Throwable {
+    InvokeDynamic.greet();
+    //BSM => new MyCallSite(Here.class, "greet", methodType(void.class))
+}
+</pre></blockquote>
+ * <p>
+ */
+@Target({ElementType.TYPE_USE,
+            // For defaulting every indy site within a class or method; cf. @SuppressWarnings:
+            ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR
+            })
+@Retention(RetentionPolicy.SOURCE)
+public @interface BootstrapMethod {
+    /** The class containing the bootstrap method. */
+    Class<?> value();
+
+    /** The name of the bootstrap method.
+     *  If this is the empty string, an instance of the bootstrap class is created,
+     *  and a constructor is invoked.
+     *  Otherwise, there must be a static method of the required name.
+     */
+    String name() default "";  // empty string denotes a constructor with 'new'
+
+    /** The argument types of the bootstrap method, as passed out by the JVM.
+     *  There is usually no reason to override the default.
+     */
+    Class<?>[] arguments() default {Class.class, String.class, MethodType.class};
+}
--- a/src/share/classes/java/dyn/CallSite.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/CallSite.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,56 +25,26 @@
 
 package java.dyn;
 
-import sun.dyn.Access;
-import sun.dyn.MemberName;
-import sun.dyn.CallSiteImpl;
+import sun.dyn.*;
+import java.util.Collection;
 
 /**
- * A {@code CallSite} reifies an {@code invokedynamic} instruction from bytecode,
- * and controls its linkage.
- * Every linked {@code CallSite} object corresponds to a distinct instance
- * of the {@code invokedynamic} instruction, and vice versa.
+ * A {@code CallSite} is a holder for a variable {@link MethodHandle},
+ * which is called its {@code target}.
+ * Every call to a {@code CallSite} is delegated to the site's current target.
  * <p>
- * Every linked {@code CallSite} object has one state variable,
- * a {@link MethodHandle} reference called the {@code target}.
- * This reference is never null.  Though it can change its value
- * successive values must always have exactly the {@link MethodType method type}
- * called for by the bytecodes of the associated {@code invokedynamic} instruction
+ * A call site is initially created in an <em>unlinked</em> state,
+ * which is distinguished by a null target variable.
+ * Before the call site may be invoked (and before certain other
+ * operations are attempted), the call site must be linked to
+ * a non-null target.
  * <p>
- * It is the responsibility of each class's
- * {@link Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
- * to produce call sites which have been pre-linked to an initial target method.
- * The required {@link MethodType type} for the target method is a parameter
- * to each bootstrap method call.
- * <p>
- * The bootstrap method may elect to produce call sites of a
- * language-specific subclass of {@code CallSite}.  In such a case,
- * the subclass may claim responsibility for initializing its target to
- * a non-null value, by overriding {@link #initialTarget}.
- * <p>
- * An {@code invokedynamic} instruction which has not yet been executed
- * is said to be <em>unlinked</em>.  When an unlinked call site is executed,
- * the containing class's bootstrap method is called to manufacture a call site,
- * for the instruction.  If the bootstrap method does not assign a non-null
- * value to the new call site's target variable, the method {@link #initialTarget}
- * is called to produce the new call site's first target method.
- * <p>
- * A freshly-created {@code CallSite} object is not yet in a linked state.
- * An unlinked {@code CallSite} object reports null for its {@code callerClass}.
- * When the JVM receives a {@code CallSite} object from a bootstrap method,
- * it first ensures that its target is non-null and of the correct type.
- * The JVM then links the {@code CallSite} object to the call site instruction,
- * enabling the {@code callerClass} to return the class in which the instruction occurs.
- * <p>
- * Next, the JVM links the instruction to the {@code CallSite}, at which point
- * any further execution of the {@code invokedynamic} instruction implicitly
- * invokes the current target of the {@code CallSite} object.
- * After this two-way linkage, both the instruction and the {@code CallSite}
- * object are said to be linked.
- * <p>
- * This state of linkage continues until the method containing the
- * dynamic call site is garbage collected, or the dynamic call site
- * is invalidated by an explicit request.
+ * A call site may be <em>relinked</em> by changing its target.
+ * The new target must be non-null and must have the same
+ * {@linkplain MethodHandle#type() type}
+ * as the previous target.
+ * Thus, though a call site can be relinked to a series of
+ * successive targets, it cannot change its type.
  * <p>
  * Linkage happens once in the lifetime of any given {@code CallSite} object.
  * Because of call site invalidation, this linkage can be repeated for
@@ -87,6 +57,10 @@
  * Here is a sample use of call sites and bootstrap methods which links every
  * dynamic call site to print its arguments:
 <blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
+&#064;BootstrapMethod(value=PrintArgsDemo.class, name="bootstrapDynamic")
+static void test() throws Throwable {
+    InvokeDynamic.baz("baz arg", 2, 3.14);
+}
 private static void printArgs(Object... args) {
   System.out.println(java.util.Arrays.deepToString(args));
 }
@@ -96,17 +70,16 @@
   Class thisClass = lookup.lookupClass();  // (who am I?)
   printArgs = lookup.findStatic(thisClass,
       "printArgs", MethodType.methodType(void.class, Object[].class));
-  Linkage.registerBootstrapMethod("bootstrapDynamic");
 }
 private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) {
   // ignore caller and name, but match the type:
   return new CallSite(MethodHandles.collectArguments(printArgs, type));
 }
 </pre></blockquote>
- * @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
  * @author John Rose, JSR 292 EG
  */
 public class CallSite
+    implements MethodHandleProvider
 {
     private static final Access IMPL_TOKEN = Access.getToken();
 
@@ -209,6 +182,7 @@
      * {@code InvokeDynamicBootstrapError}, which in turn causes the
      * linkage of the {@code invokedynamic} instruction to terminate
      * abnormally.
+     * @deprecated transitional form defined in EDR but removed in PFD
      */
     protected MethodHandle initialTarget(Class<?> callerClass, String name, MethodType type) {
         throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+name+type);
@@ -278,16 +252,44 @@
      */
     @Override
     public String toString() {
-        StringBuilder buf = new StringBuilder("CallSite#");
-        buf.append(hashCode());
-        if (!isLinked())
-            buf.append("[unlinked]");
-        else
-            buf.append("[")
-                .append("from ").append(vmmethod.getDeclaringClass().getName())
-                .append(" : ").append(getTarget().type())
-                .append(" => ").append(getTarget())
-                .append("]");
-        return buf.toString();
+        return "CallSite"+(target == null ? "" : target.type());
     }
+
+    /**
+     * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+     * Produce a method handle equivalent to an invokedynamic instruction
+     * which has been linked to this call site.
+     * <p>If this call site is a {@link ConstantCallSite}, this method
+     * simply returns the call site's target, since that will not change.
+     * <p>Otherwise, this method is equivalent to the following code:
+     * <p><blockquote><pre>
+     * MethodHandle getTarget, invoker, result;
+     * getTarget = MethodHandles.lookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
+     * invoker = MethodHandles.exactInvoker(this.type());
+     * result = MethodHandles.foldArguments(invoker, getTarget)
+     * </pre></blockquote>
+     * @return a method handle which always invokes this call site's current target
+     */
+    public final MethodHandle dynamicInvoker() {
+        if (this instanceof ConstantCallSite)
+            return getTarget();  // will not change dynamically
+        MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, GET_TARGET, this);
+        MethodHandle invoker = MethodHandles.exactInvoker(this.type());
+        return MethodHandles.foldArguments(invoker, getTarget);
+    }
+    private static final MethodHandle GET_TARGET;
+    static {
+        try {
+            GET_TARGET = MethodHandles.Lookup.IMPL_LOOKUP.
+                findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
+        } catch (NoAccessException ignore) {
+            throw new InternalError();
+        }
+    }
+
+    /** Implementation of {@link MethodHandleProvider} which returns {@code this.dynamicInvoker()}. */
+    public final MethodHandle asMethodHandle() { return dynamicInvoker(); }
+
+    /** Implementation of {@link MethodHandleProvider}, which returns {@code this.dynamicInvoker().asType(type)}. */
+    public final MethodHandle asMethodHandle(MethodType type) { return dynamicInvoker().asType(type); }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/dyn/ClassValue.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.dyn;
+
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Lazily associate a computed value with (potentially) every class.
+ * @author John Rose, JSR 292 EG
+ */
+public abstract class ClassValue<T> {
+    /**
+     * Compute the given class's derived value for this {@code ClassValue}.
+     * <p>
+     * This method will be invoked within the first thread that accesses
+     * the value with the {@link #get}.
+     * <p>
+     * Normally, this method is invoked at most once per class,
+     * but it may be invoked again in case of subsequent invocations
+     * of {@link #remove} followed by {@link #get}.
+     *
+     * @return the computed value for this thread-local
+     */
+    protected abstract T computeValue(Class<?> type);
+
+    /**
+     * Creates a new class value.
+     */
+    protected ClassValue() {
+    }
+
+    /**
+     * Returns the value for the given class.
+     * If no value has yet been computed, it is obtained by
+     * by an invocation of the {@link #computeValue} method.
+     * <p>
+     * The actual installation of the value on the class
+     * is performed while the class's synchronization lock
+     * is held.  At that point, if racing threads have
+     * computed values, one is chosen, and returned to
+     * all the racing threads.
+     *
+     * @return the current thread's value of this thread-local
+     */
+    public T get(Class<?> type) {
+        ClassValueMap map = getMap(type);
+        if (map != null) {
+            Object x = map.get(this);
+            if (x != null) {
+                return (T) map.unmaskNull(x);
+            }
+        }
+        return setComputedValue(type);
+    }
+
+    /**
+     * Removes the associated value for the given class.
+     * If this value is subsequently {@linkplain #get read} for the same class,
+     * its value will be reinitialized by invoking its {@link #computeValue} method.
+     * This may result in an additional invocation of the
+     * {@code computeValue} method for the given class.
+     */
+    public void remove(Class<?> type) {
+        ClassValueMap map = getMap(type);
+        if (map != null) {
+            synchronized (map) {
+                map.remove(this);
+            }
+        }
+    }
+
+    /// Implementation...
+
+    /** The hash code for this type is based on the identity of the object,
+     *  and is well-dispersed for power-of-two tables.
+     */
+    public final int hashCode() { return hashCode; }
+    private final int hashCode = HASH_CODES.getAndAdd(0x61c88647);
+    private static final AtomicInteger HASH_CODES = new AtomicInteger();
+
+    private static final AtomicInteger STORE_BARRIER = new AtomicInteger();
+
+    /** Slow path for {@link #get}. */
+    private T setComputedValue(Class<?> type) {
+        ClassValueMap map = getMap(type);
+        if (map == null) {
+            map = initializeMap(type);
+        }
+        T value = computeValue(type);
+        STORE_BARRIER.lazySet(0);
+        // All stores pending from computeValue are completed.
+        synchronized (map) {
+            // Warm up the table with a null entry.
+            map.preInitializeEntry(this);
+        }
+        // All stores pending from table expansion are completed.
+        synchronized (map) {
+            value = (T) map.initializeEntry(this, value);
+            // One might fear a possible race condition here
+            // if the code for map.put has flushed the write
+            // to map.table[*] before the writes to the Map.Entry
+            // are done.  This is not possible, since we have
+            // warmed up the table with an empty entry.
+        }
+        return value;
+    }
+
+    // Replace this map by a per-class slot.
+    private static final WeakHashMap<Class<?>, ClassValueMap> ROOT
+        = new WeakHashMap<Class<?>, ClassValueMap>();
+
+    private static ClassValueMap getMap(Class<?> type) {
+        return ROOT.get(type);
+    }
+
+    private static ClassValueMap initializeMap(Class<?> type) {
+        synchronized (ClassValue.class) {
+            ClassValueMap map = ROOT.get(type);
+            if (map == null)
+                ROOT.put(type, map = new ClassValueMap());
+            return map;
+        }
+    }
+
+    static class ClassValueMap extends WeakHashMap<ClassValue, Object> {
+        /** Make sure this table contains an Entry for the given key, even if it is empty. */
+        void preInitializeEntry(ClassValue key) {
+            if (!this.containsKey(key))
+                this.put(key, null);
+        }
+        /** Make sure this table contains a non-empty Entry for the given key. */
+        Object initializeEntry(ClassValue key, Object value) {
+            Object prior = this.get(key);
+            if (prior != null) {
+                return unmaskNull(prior);
+            }
+            this.put(key, maskNull(value));
+            return value;
+        }
+
+        Object maskNull(Object x) {
+            return x == null ? this : x;
+        }
+        Object unmaskNull(Object x) {
+            return x == this ? null : x;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/dyn/ConstantCallSite.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.dyn;
+
+/**
+ * A {@code ConstantCallSite} is a {@link CallSite} whose target is permanent, and can never be changed.
+ * The only way to relink an {@code invokedynamic} instruction bound to a {@code ConstantCallSite} is
+ * to invalidate the instruction as a whole.
+ * @author John Rose, JSR 292 EG
+ */
+public class ConstantCallSite extends CallSite {
+    /** Create a call site with a permanent target. */
+    public ConstantCallSite(MethodHandle target) {
+        super(target);
+    }
+    /** Throw an {@link IllegalArgumentException}, because this kind of call site cannot change its target. */
+    @Override public final void setTarget(MethodHandle ignore) {
+        throw new IllegalArgumentException("ConstantCallSite");
+    }
+}
--- a/src/share/classes/java/dyn/InvokeDynamic.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/InvokeDynamic.java	Thu Nov 11 18:46:02 2010 -0800
@@ -35,7 +35,7 @@
  * The target method is a property of the reified {@linkplain CallSite call site object}
  * which is linked to each active {@code invokedynamic} instruction.
  * The call site object is initially produced by a
- * {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
+ * {@linkplain BootstrapMethod bootstrap method}
  * associated with the class whose bytecodes include the dynamic call site.
  * <p>
  * The type {@code InvokeDynamic} has no particular meaning as a
@@ -45,22 +45,31 @@
  * It may be imported for ease of use.
  * <p>
  * Here are some examples:
- * <p><blockquote><pre>
- * Object x; String s; int i;
- * x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
- * s = InvokeDynamic.&lt;String&gt;hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
- * InvokeDynamic.&lt;void&gt;cogito(); // cogito()V
- * i = InvokeDynamic.&lt;int&gt;#"op:+"(2, 3); // "op:+"(II)I
- * </pre></blockquote>
+<blockquote><pre><!-- see indy-demo/src/JavaDocExamples.java -->
+&#064;BootstrapMethod(value=Here.class, name="bootstrapDynamic")
+static void example() throws Throwable {
+    Object x; String s; int i;
+    x = InvokeDynamic.greet("world"); // greet(Ljava/lang/String;)Ljava/lang/Object;
+    s = (String) InvokeDynamic.hail(x); // hail(Ljava/lang/Object;)Ljava/lang/String;
+    InvokeDynamic.cogito(); // cogito()V
+    i = (int) InvokeDynamic.#"op:+"(2, 3); // "op:+"(II)I
+}
+static MethodHandle bootstrapDynamic(Class caller, String name, MethodType type) { ... }
+</pre></blockquote>
  * Each of the above calls generates a single invokedynamic instruction
  * with the name-and-type descriptors indicated in the comments.
+ * <p>
  * The argument types are taken directly from the actual arguments,
- * while the return type is taken from the type parameter.
- * (This type parameter may be a primtive, and it defaults to {@code Object}.)
+ * while the return type corresponds to the target of the assignment.
+ * (Currently, the return type must be given as a false type parameter.
+ * This type parameter is an irregular use of the generic type syntax,
+ * and is likely to change in favor of a convention based on target typing.)
+ * <p>
  * The final example uses a special syntax for uttering non-Java names.
  * Any name legal to the JVM may be given between the double quotes.
+ * <p>
  * None of these calls is complete without a bootstrap method,
- * which must be registered by the static initializer of the enclosing class.
+ * which must be declared for the enclosing class or method.
  * @author John Rose, JSR 292 EG
  */
 @MethodHandle.PolymorphicSignature
--- a/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/InvokeDynamicBootstrapError.java	Thu Nov 11 18:46:02 2010 -0800
@@ -28,15 +28,11 @@
 /**
  * Thrown to indicate that an {@code invokedynamic} instruction has
  * failed to find its
- * {@linkplain Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method},
+ * {@linkplain BootstrapMethod bootstrap method},
  * or the bootstrap method has
  * failed to provide a
  * {@linkplain CallSite} call site with a non-null {@linkplain MethodHandle target}
  * of the correct {@linkplain MethodType method type}.
- * <p>
- * The bootstrap method must have been declared during a class's initialization
- * by a call to one of the overloadings of
- * {@link Linkage#registerBootstrapMethod registerBootstrapMethod}.
  *
  * @author John Rose, JSR 292 EG
  * @since 1.7
--- a/src/share/classes/java/dyn/JavaMethodHandle.java	Tue Nov 02 22:15:35 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/*
- * Copyright (c) 2008, 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.dyn;
-
-import sun.dyn.Access;
-
-/**
- * A Java method handle is a deprecated proposal for extending
- * the basic method handle type with additional
- * programmer defined methods and fields.
- * Its behavior as a method handle is determined at instance creation time,
- * by providing the new instance with an "entry point" method handle
- * to handle calls.  This entry point must accept a leading argument
- * whose type is the Java method handle itself or a supertype, and the
- * entry point is always called with the Java method handle itself as
- * the first argument.  This is similar to ordinary virtual methods, which also
- * accept the receiver object {@code this} as an implicit leading argument.
- * The {@code MethodType} of the Java method handle is the same as that
- * of the entry point method handle, with the leading parameter type
- * omitted.
- * <p>
- * Here is an example of usage, creating a hybrid object/functional datum:
- * <p><blockquote><pre>
- * class Greeter extends JavaMethodHandle {
- *     private String greeting = "hello";
- *     public void setGreeting(String s) { greeting = s; }
- *     public void run() { System.out.println(greeting+", "+greetee); }
- *     private final String greetee;
- *     Greeter(String greetee) {
- *         super(RUN); // alternatively, super("run")
- *         this.greetee = greetee;
- *     }
- *     // the entry point function is computed once:
- *     private static final MethodHandle RUN
- *         = MethodHandles.lookup().findVirtual(Greeter.class, "run",
- *               MethodType.make(void.class));
- * }
- * // class Main { public static void main(String... av) { ...
- * Greeter greeter = new Greeter("world");
- * greeter.run();  // prints "hello, world"
- * // Statically typed method handle invocation (most direct):
- * MethodHandle mh = greeter;
- * mh.&lt;void&gt;invokeExact();  // also prints "hello, world"
- * // Dynamically typed method handle invocation:
- * MethodHandles.invokeExact(greeter);  // also prints "hello, world"
- * greeter.setGreeting("howdy");
- * mh.invokeExact();  // prints "howdy, world" (object-like mutable behavior)
- * </pre></blockquote>
- * <p>
- * In the example of {@code Greeter}, the method {@code run} provides the entry point.
- * The entry point need not be a constant value; it may be independently
- * computed in each call to the constructor.  The entry point does not
- * even need to be a method on the {@code Greeter} class, though
- * that is the typical case.
- * <p>
- * The entry point may also be provided symbolically, in which case the the
- * {@code JavaMethodHandle} constructor performs the lookup of the entry point.
- * This makes it possible to use {@code JavaMethodHandle} to create an anonymous
- * inner class:
- * <p><blockquote><pre>
- * // We can also do this with symbolic names and/or inner classes:
- * MethodHandles.invokeExact(new JavaMethodHandle("yow") {
- *     void yow() { System.out.println("yow, world"); }
- * });
- * </pre></blockquote>
- * <p>
- * Here is similar lower-level code which works in terms of a bound method handle.
- * <p><blockquote><pre>
- *     class Greeter {
- *         public void run() { System.out.println("hello, "+greetee); }
- *         private final String greetee;
- *         Greeter(String greetee) { this.greetee = greetee; }
- *         // the entry point function is computed once:
- *         private static final MethodHandle RUN
- *             = MethodHandles.findVirtual(Greeter.class, "run",
- *                   MethodType.make(void.class));
- *     }
- *     // class Main { public static void main(String... av) { ...
- *     Greeter greeter = new Greeter("world");
- *     greeter.run();  // prints "hello, world"
- *     MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
- *     mh.invokeExact();  // also prints "hello, world"
- * </pre></blockquote>
- * Note that the method handle must be separately created as a view on the base object.
- * This increases footprint, complexity, and dynamic indirections.
- * <p>
- * Here is a pure functional value expressed most concisely as an anonymous inner class:
- * <p><blockquote><pre>
- *     // class Main { public static void main(String... av) { ...
- *     final String greetee = "world";
- *     MethodHandle greeter = new JavaMethodHandle("run") {
- *         private void run() { System.out.println("hello, "+greetee); }
- *     }
- *     greeter.invokeExact();  // prints "hello, world"
- * </pre></blockquote>
- * <p>
- * Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
- * and instantiated as an anonymous class.  The data structure is a handle to 1-D array,
- * with a specialized index type (long).  It is created by inner class, and uses
- * signature-polymorphic APIs throughout.
- * <p><blockquote><pre>
- *     abstract class AssignableMethodHandle extends JavaMethodHandle {
- *       private final MethodHandle setter;
- *       public MethodHandle setter() { return setter; }
- *       public AssignableMethodHandle(String get, String set) {
- *         super(get);
- *         MethodType getType = this.type();
- *         MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
- *         this.setter = MethodHandles.publicLookup().bind(this, set, setType);
- *       }
- *     }
- *     // class Main { public static void main(String... av) { ...
- *     final Number[] stuff = { 123, 456 };
- *     AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
- *         public Number get(long i)           { return stuff[(int)i]; }
- *         public void   set(long i, Object x) {        stuff[(int)i] = x; }
- *     }
- *     int x = (Integer) stuffPtr.&lt;Number&gt;invokeExact(1L);  // 456
- *     stuffPtr.setter().&lt;void&gt;invokeExact(0L, (Number) 789);  // replaces 123 with 789
- * </pre></blockquote>
- * @see MethodHandle
- * @deprecated The JSR 292 EG intends to replace {@code JavaMethodHandle} with
- * an interface-based API for mixing method handle behavior with other classes.
- * @author John Rose, JSR 292 EG
- */
-public abstract class JavaMethodHandle
-        // Note: This is an implementation inheritance hack, and will be removed
-        // with a JVM change which moves the required hidden behavior onto this class.
-        extends sun.dyn.BoundMethodHandle
-{
-    private static final Access IMPL_TOKEN = Access.getToken();
-
-    /**
-     * When creating a {@code JavaMethodHandle}, the actual method handle
-     * invocation behavior will be delegated to the specified {@code entryPoint}.
-     * This may be any method handle which can take the newly constructed object
-     * as a leading parameter.
-     * <p>
-     * The method handle type of {@code this} (i.e, the fully constructed object)
-     * will be {@code entryPoint}, minus the leading argument.
-     * The leading argument will be bound to {@code this} on every method
-     * handle invocation.
-     * @param entryPoint the method handle to handle calls
-     */
-    protected JavaMethodHandle(MethodHandle entryPoint) {
-        super(entryPoint);
-    }
-
-    /**
-     * Create a method handle whose entry point is a non-static method
-     * visible in the exact (most specific) class of
-     * the newly constructed object.
-     * <p>
-     * The method is specified by name and type, as if via this expression:
-     * {@code MethodHandles.lookup().findVirtual(this.getClass(), name, type)}.
-     * The class defining the method might be an anonymous inner class.
-     * <p>
-     * The method handle type of {@code this} (i.e, the fully constructed object)
-     * will be the given method handle type.
-     * A call to {@code this} will invoke the selected method.
-     * The receiver argument will be bound to {@code this} on every method
-     * handle invocation.
-     * <p>
-     * <i>Rationale:</i>
-     * Although this constructor may seem to be a mere luxury,
-     * it is not subsumed by the more general constructor which
-     * takes any {@code MethodHandle} as the entry point argument.
-     * In order to convert an entry point name to a method handle,
-     * the self-class of the object is required (in order to do
-     * the lookup).  The self-class, in turn, is generally not
-     * available at the time of the constructor invocation,
-     * due to the rules of Java and the JVM verifier.
-     * One cannot call {@code this.getClass()}, because
-     * the value of {@code this} is inaccessible at the point
-     * of the constructor call.  (Changing this would require
-     * change to the Java language, verifiers, and compilers.)
-     * In particular, this constructor allows {@code JavaMethodHandle}s
-     * to be created in combination with the anonymous inner class syntax.
-     * @param entryPointName the name of the entry point method
-     * @param type (optional) the desired type of the method handle
-     */
-    protected JavaMethodHandle(String entryPointName, MethodType type) {
-        super(entryPointName, type, true);
-
-    }
-
-    /**
-     * Create a method handle whose entry point is a non-static method
-     * visible in the exact (most specific) class of
-     * the newly constructed object.
-     * <p>
-     * The method is specified only by name.
-     * There must be exactly one method of that name visible in the object class,
-     * either inherited or locally declared.
-     * (That is, the method must not be overloaded.)
-     * <p>
-     * The method handle type of {@code this} (i.e, the fully constructed object)
-     * will be the same as the type of the selected non-static method.
-     * The receiver argument will be bound to {@code this} on every method
-     * handle invocation.
-     * <p>ISSUE: This signature wildcarding feature does not correspond to
-     * any MethodHandles.Lookup API element.  Can we eliminate it?
-     * Alternatively, it is useful for naming non-overloaded methods.
-     * Shall we make type arguments optional in the Lookup methods,
-     * throwing an error in cases of ambiguity?
-     * <p>
-     * For this method's rationale, see the documentation
-     * for {@link #JavaMethodHandle(String,MethodType)}.
-     * @param entryPointName the name of the entry point method
-     */
-    protected JavaMethodHandle(String entryPointName) {
-        super(entryPointName, (MethodType) null, false);
-    }
-}
--- a/src/share/classes/java/dyn/Linkage.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/Linkage.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,7 +25,6 @@
 
 package java.dyn;
 
-import java.lang.annotation.Annotation;
 import java.dyn.MethodHandles.Lookup;
 import java.util.WeakHashMap;
 import sun.dyn.Access;
@@ -56,11 +55,7 @@
      * <li>the class containing the {@code invokedynamic} instruction, for which the bootstrap method was registered
      * <li>the name of the method being invoked (a {@link String})
      * <li>the type of the method being invoked (a {@link MethodType})
-     * <li><em>TBD</em> optionally, an unordered array of {@link Annotation}s attached to the call site
-     *     <em>(Until this feature is implemented, this will always receive an empty array.)</em>
      * </ul>
-     * <em>(TBD: The final argument type may be missing from the method handle's type.
-     * Additional arguments may be added in the future.)</em>
      * The bootstrap method acts as a factory method which accepts the given arguments
      * and returns a {@code CallSite} object (possibly of a subclass of {@code CallSite}).
      * <p>
@@ -86,6 +81,7 @@
      *            or is already running in another thread
      * @exception SecurityException if there is a security manager installed,
      *            and a {@link LinkagePermission} check fails for "registerBootstrapMethod"
+     * @deprecated Use @{@link BootstrapMethod} annotations instead
      */
     public static
     void registerBootstrapMethod(Class callerClass, MethodHandle bootstrapMethod) {
@@ -97,14 +93,9 @@
 
     static private void checkBSM(MethodHandle mh) {
         if (mh == null)  throw newIllegalArgumentException("null bootstrap method");
-        if (mh.type() == BOOTSTRAP_METHOD_TYPE_2)
-            // For now, always pass an empty array for the Annotations argument
-            mh = MethodHandles.insertArguments(mh, BOOTSTRAP_METHOD_TYPE_2.parameterCount()-1,
-                                               (Object)NO_ANNOTATIONS);
         if (mh.type() == BOOTSTRAP_METHOD_TYPE)  return;
         throw new WrongMethodTypeException(mh.toString());
     }
-    static private final Annotation[] NO_ANNOTATIONS = { };
 
     /**
      * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
@@ -115,6 +106,7 @@
      * @throws NoSuchMethodException if there is no such method
      * @throws IllegalStateException if the caller class's static initializer
      *         has already run, or is already running in another thread
+     * @deprecated Use @{@link BootstrapMethod} annotations instead
      */
     public static
     void registerBootstrapMethod(Class<?> runtime, String name) {
@@ -131,6 +123,7 @@
      * @throws IllegalArgumentException if there is no such method
      * @throws IllegalStateException if the caller class's static initializer
      *         has already run, or is already running in another thread
+     * @deprecated Use @{@link BootstrapMethod} annotations instead
      */
     public static
     void registerBootstrapMethod(String name) {
@@ -142,18 +135,10 @@
     void registerBootstrapMethodLookup(Class<?> callerClass, Class<?> runtime, String name) {
         Lookup lookup = new Lookup(IMPL_TOKEN, callerClass);
         MethodHandle bootstrapMethod;
-        // Try both types.  TBD
         try {
-            bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE_2);
+            bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
         } catch (NoAccessException ex) {
-            bootstrapMethod = null;
-        }
-        if (bootstrapMethod == null) {
-            try {
-                bootstrapMethod = lookup.findStatic(runtime, name, BOOTSTRAP_METHOD_TYPE);
-            } catch (NoAccessException ex) {
-                throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
-            }
+            throw new IllegalArgumentException("no such bootstrap method in "+runtime+": "+name, ex);
         }
         checkBSM(bootstrapMethod);
         MethodHandleImpl.registerBootstrap(IMPL_TOKEN, callerClass, bootstrapMethod);
@@ -172,6 +157,7 @@
      *            and the immediate caller of this method is not in the same
      *            package as the caller class
      *            and a {@link LinkagePermission} check fails for "getBootstrapMethod"
+     * @deprecated
      */
     public static
     MethodHandle getBootstrapMethod(Class callerClass) {
@@ -188,10 +174,6 @@
     public static final MethodType BOOTSTRAP_METHOD_TYPE
             = MethodType.methodType(CallSite.class,
                                     Class.class, String.class, MethodType.class);
-    static final MethodType BOOTSTRAP_METHOD_TYPE_2
-            = MethodType.methodType(CallSite.class,
-                                    Class.class, String.class, MethodType.class,
-                                    Annotation[].class);
 
     /**
      * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
--- a/src/share/classes/java/dyn/LinkagePermission.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/LinkagePermission.java	Thu Nov 11 18:46:02 2010 -0800
@@ -31,6 +31,7 @@
 import java.util.StringTokenizer;
 
 /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
  * This class is for managing runtime permission checking for
  * operations performed by methods in the {@link Linkage} class.
  * Like a {@link RuntimePermission}, on which it is modeled,
@@ -52,13 +53,6 @@
  * </tr>
  *
  * <tr>
- *   <td>registerBootstrapMethod.{class name}</td>
- *   <td>Specifying a bootstrap method for {@code invokedynamic} instructions within a class of the given name</td>
- *   <td>An attacker could attempt to attach a bootstrap method to a class which
- *       has just been loaded, thus gaining control of its {@code invokedynamic} calls.</td>
- * </tr>
- *
- * <tr>
  *   <td>invalidateAll</td>
  *   <td>Force the relinking of invokedynamic call sites everywhere.</td>
  *   <td>This could allow an attacker to slow down the system,
@@ -73,8 +67,9 @@
  *   <td>See {@code invalidateAll}.</td>
  * </tr>
  * </table>
+ * <p>ISSUE: Is this still needed?
  *
- * @see java.security.RuntimePermission
+ * @see java.lang.RuntimePermission
  * @see java.lang.SecurityManager
  *
  * @author John Rose, JSR 292 EG
@@ -86,7 +81,7 @@
     /**
      * Create a new LinkagePermission with the given name.
      * The name is the symbolic name of the LinkagePermission, such as
-     * "registerBootstrapMethod", "invalidateCallerClass.*", etc. An asterisk
+     * "invalidateCallerClass.*", etc. An asterisk
      * may appear at the end of the name, following a ".", or by itself, to
      * signify a wildcard match.
      *
--- a/src/share/classes/java/dyn/MethodHandle.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/MethodHandle.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,11 +36,13 @@
 /**
  * A method handle is a typed, directly executable reference to a method,
  * constructor, field, or similar low-level operation, with optional
- * conversion or substitution of arguments or return values.
+ * transformations of arguments or return values.
+ * (These transformations include conversion, insertion, deletion,
+ * substitution.  See the methods of this class and of {@link MethodHandles}.)
  * <p>
  * Method handles are strongly typed according to signature.
  * They are not distinguished by method name or enclosing class.
- * A method handle must be invoked under a signature which exactly matches
+ * A method handle must be invoked under a signature which matches
  * the method handle's own {@link MethodType method type}.
  * <p>
  * Every method handle confesses its type via the {@code type} accessor.
@@ -174,9 +176,10 @@
  * merely a documentation convention.  These type parameters do
  * not play a role in type-checking method handle invocations.
  * <p>
- * Note: Like classes and strings, method handles that correspond directly
- * to fields and methods can be represented directly as constants to be
- * loaded by {@code ldc} bytecodes.
+ * Like classes and strings, method handles that correspond to accessible
+ * fields, methods, and constructors can be represented directly
+ * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
+ * Loading such a constant causes the component classes of its type to be loaded as necessary.
  *
  * @see MethodType
  * @see MethodHandles
@@ -186,6 +189,7 @@
         // Note: This is an implementation inheritance hack, and will be removed
         // with a JVM change which moves the required hidden state onto this class.
         extends MethodHandleImpl
+        implements MethodHandleProvider
 {
     private static Access IMPL_TOKEN = Access.getToken();
 
@@ -197,7 +201,7 @@
      * those methods which are signature polymorphic.
      */
     @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.TYPE})
-    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
+    @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
     @interface PolymorphicSignature { }
 
     private MethodType type;
@@ -274,10 +278,14 @@
      * and performing simple conversions for arguments and return types.
      * The signature at the call site of {@code invokeGeneric} must
      * have the same arity as this method handle's {@code type}.
-     * The same conversions are allowed on arguments or return values as are supported by
-     * by {@link MethodHandles#convertArguments}.
+     * <p>
      * If the call site signature exactly matches this method handle's {@code type},
      * the call proceeds as if by {@link #invokeExact}.
+     * <p>
+     * Otherwise, the call proceeds as if this method handle were first
+     * adjusted by calling {@link #asType} to adjust this method handle
+     * to the required type, and then the call proceeds as if by
+     * {@link #invokeExact} on the adjusted method handle.
      */
     public final native @PolymorphicSignature <R,A> R invokeGeneric(A... args) throws Throwable;
 
@@ -538,4 +546,10 @@
     public final MethodHandle bindTo(Object x) {
         return MethodHandles.insertArguments(this, 0, x);
     }
+
+    /** Implementation of {@link MethodHandleProvider}, which returns {@code this}. */
+    public final MethodHandle asMethodHandle() { return this; }
+
+    /** Implementation of {@link MethodHandleProvider}, which returns {@code this.asType(type)}. */
+    public final MethodHandle asMethodHandle(MethodType type) { return this.asType(type); }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/dyn/MethodHandleProvider.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.dyn;
+
+/**
+ * An interface for an object to provide a target {@linkplain MethodHandle method handle} to a {@code invokedynamic} instruction.
+ * There are many function-like objects in various Java APIs.
+ * This interface provides a standard way for such function-like objects to be bound
+ * to a dynamic call site, by providing a view of their behavior in the form of a low-level method handle.
+ * <p>
+ * The type {@link MethodHandle} is a concrete class whose implementation
+ * hierarchy (if any) may be tightly coupled to the underlying JVM implementation.
+ * It cannot also serve as a base type for user-defined functional APIs.
+ * For this reason, {@code MethodHandle} cannot be subclassed to add new
+ * behavior to method handles.  But this interface can be used to provide
+ * a link between a user-defined function and the {@code invokedynamic}
+ * instruction and the method handle API.
+ */
+public interface MethodHandleProvider {
+    /** Produce a method handle which will serve as a behavioral proxy for the current object.
+     *  The type and invocation behavior of the proxy method handle are user-defined,
+     *  and should have some relation to the intended meaning of the original object itself.
+     *  <p>
+     *  The current object may have a changeable behavior.
+     *  For example, {@link CallSite} has a {@code setTarget} method which changes its invocation.
+     *  In such a case, it is <em>incorrect</em> for {@code asMethodHandle} to return
+     *  a method handle whose behavior may diverge from that of the current object.
+     *  Rather, the returned method handle must stably and permanently access
+     *  the behavior of the current object, even if that behavior is changeable.
+     *  <p>
+     *  The reference identity of the proxy method handle is not guaranteed to
+     *  have any particular relation to the reference identity of the object.
+     *  In particular, several objects with the same intended meaning could
+     *  share a common method handle, or the same object could return different
+     *  method handles at different times.  In the latter case, the different
+     *  method handles should have the same type and invocation behavior,
+     *  and be usable from any thread at any time.
+     *  In particular, if a MethodHandleProvider is bound to an <code>invokedynamic</code>
+     *  call site, the proxy method handle extracted at the time of binding
+     *  will be used for an unlimited time, until the call site is rebound.
+     *  <p>
+     *  The type {@link MethodHandle} itself implements {@code MethodHandleProvider}, and
+     *  for this method simply returns {@code this}.
+     */
+    public MethodHandle asMethodHandle();
+
+    /** Produce a method handle of a given type which will serve as a behavioral proxy for the current object.
+     *  As for the no-argument version {@link #asMethodHandle()}, the invocation behavior of the
+     *  proxy method handle is user-defined.  But the type must be the given type,
+     *  or else a {@link WrongMethodTypeException} must be thrown.
+     *  <p>
+     *  If the current object somehow represents a variadic or overloaded behavior,
+     *  the method handle returned for a given type might represent only a subset of
+     *  the current object's repertoire of behaviors, which correspond to that type.
+     */
+    public MethodHandle asMethodHandle(MethodType type) throws WrongMethodTypeException;
+}
--- a/src/share/classes/java/dyn/MethodHandles.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/MethodHandles.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,15 +25,12 @@
 
 package java.dyn;
 
-import java.lang.reflect.Constructor;
+import java.lang.reflect.*;
 import sun.dyn.Access;
 import sun.dyn.MemberName;
 import sun.dyn.MethodHandleImpl;
 import sun.dyn.util.VerifyAccess;
 import sun.dyn.util.Wrapper;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -81,6 +78,14 @@
      * Return a {@link Lookup lookup object} which is trusted minimally.
      * It can only be used to create method handles to
      * publicly accessible fields and methods.
+     * <p>
+     * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
+     * of this lookup object will be {@link java.lang.Object}.
+     * <p>
+     * The lookup class can be changed to any other class {@code C} using an expression of the form
+     * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
+     * Since all classes have equal access to public names,
+     * such a change would confer no new access rights.
      */
     public static Lookup publicLookup() {
         return Lookup.PUBLIC_LOOKUP;
@@ -90,9 +95,10 @@
      * A <em>lookup object</em> is a factory for creating method handles,
      * when the creation requires access checking.
      * Method handles do not perform
-     * access checks when they are called; this is a major difference
+     * access checks when they are called, but rather when they are created.
+     * (This is a major difference
      * from reflective {@link Method}, which performs access checking
-     * against every caller, on every call.
+     * against every caller, on every call.)
      * Therefore, method handle access
      * restrictions must be enforced when a method handle is created.
      * The caller class against which those restrictions are enforced
@@ -107,7 +113,7 @@
      * It may then use this factory to create method handles on
      * all of its methods, including private ones.
      * It may also delegate the lookup (e.g., to a metaobject protocol)
-     * by passing the {@code Lookup} object to other code.
+     * by passing the lookup object to other code.
      * If this other code creates method handles, they will be access
      * checked against the original lookup class, and not with any higher
      * privileges.
@@ -125,23 +131,28 @@
      * It can also fail if a security manager is installed and refuses
      * access.  In any of these cases, an exception will be
      * thrown from the attempted lookup.
+     * <p>
      * In general, the conditions under which a method handle may be
      * created for a method {@code M} are exactly as restrictive as the conditions
      * under which the lookup class could have compiled a call to {@code M}.
-     * At least some of these error conditions are likely to be
-     * represented by checked exceptions in the final version of this API.
+     * This rule is applied even if the Java compiler might have created
+     * an wrapper method to access a private method of another class
+     * in the same top-level declaration.
+     * For example, a lookup object created for a nested class {@code C.D}
+     * can access private members within other related classes such as
+     * {@code C}, {@code C.D.E}, or {@code C.B}.
      */
     public static final
     class Lookup {
         /** The class on behalf of whom the lookup is being performed. */
         private final Class<?> lookupClass;
 
-        /** The allowed sorts of members which may be looked up (public, etc.), with STRICT for package. */
+        /** The allowed sorts of members which may be looked up (public, etc.), with STATIC for package. */
         private final int allowedModes;
 
         private static final int
             PUBLIC    = Modifier.PUBLIC,
-            PACKAGE   = Modifier.STRICT,
+            PACKAGE   = Modifier.STATIC,
             PROTECTED = Modifier.PROTECTED,
             PRIVATE   = Modifier.PRIVATE,
             ALL_MODES = (PUBLIC | PACKAGE | PROTECTED | PRIVATE),
@@ -155,8 +166,10 @@
         /** Which class is performing the lookup?  It is this class against
          *  which checks are performed for visibility and access permissions.
          *  <p>
-         *  This value is null if and only if this lookup was produced
-         *  by {@link MethodHandles#publicLookup}.
+         *  The class implies a maximum level of access permission,
+         *  but the permissions may be additionally limited by the bitmask
+         *  {@link #lookupModes}, which controls whether non-public members
+         *  can be accessed.
          */
         public Class<?> lookupClass() {
             return lookupClass;
@@ -168,10 +181,15 @@
         }
 
         /** Which types of members can this lookup object produce?
-         *  The result is a bit-mask of the modifier bits PUBLIC, PROTECTED, PRIVATE, and STRICT.
-         *  The modifier bit STRICT stands in for the (non-existent) package protection mode.
+         *  The result is a bit-mask of the {@link Modifier} bits
+         *  {@linkplain Modifier#PUBLIC PUBLIC (0x01)},
+         *  {@linkplain Modifier#PROTECTED PROTECTED (0x02)},
+         *  {@linkplain Modifier#PRIVATE PRIVATE (0x04)},
+         *  and {@linkplain Modifier#STATIC STATIC (0x08)}.
+         *  The modifier bit {@code STATIC} stands in for the package protection mode,
+         *  which does not have an explicit modifier bit.
          */
-        int lookupModes() {
+        public int lookupModes() {
             return allowedModes & ALL_MODES;
         }
 
@@ -621,32 +639,32 @@
 
         /// Helper methods, all package-private.
 
-        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) {
+        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
             int mods = (isStatic ? Modifier.STATIC : 0);
             return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
         }
 
-        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) {
+        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
             int mods = (isStatic ? Modifier.STATIC : 0);
             return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull());
         }
 
         MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
-                                 boolean searchSupers, Class<?> specialCaller) {
+                                 boolean searchSupers, Class<?> specialCaller) throws NoAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
             int mods = (isStatic ? Modifier.STATIC : 0);
             return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller);
         }
 
-        void checkSymbolicClass(Class<?> refc) {
+        void checkSymbolicClass(Class<?> refc) throws NoAccessException {
             Class<?> caller = lookupClassOrNull();
             if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
                 throw newNoAccessException("symbolic reference class is not public", new MemberName(refc), caller);
         }
 
-        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) {
+        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws NoAccessException {
             String message;
             if (m.isConstructor())
                 message = "expected a method, not a constructor";
@@ -659,7 +677,7 @@
             throw newNoAccessException(message, m, lookupClass());
         }
 
-        void checkAccess(Class<?> refc, MemberName m) {
+        void checkAccess(Class<?> refc, MemberName m) throws NoAccessException {
             int allowedModes = this.allowedModes;
             if (allowedModes == TRUSTED)  return;
             int mods = m.getModifiers();
@@ -695,14 +713,14 @@
             return "member is private to package";
         }
 
-        void checkSpecialCaller(Class<?> specialCaller) {
+        void checkSpecialCaller(Class<?> specialCaller) throws NoAccessException {
             if (allowedModes == TRUSTED)  return;
             if (!VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))
                 throw newNoAccessException("no private access for invokespecial",
                                            new MemberName(specialCaller), lookupClass());
         }
 
-        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) {
+        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws NoAccessException {
             // The accessing class only has the right to use a protected member
             // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
             if (!method.isProtected() || method.isStatic()
@@ -712,7 +730,7 @@
             else
                 return restrictReceiver(method, mh, lookupClass());
         }
-        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) {
+        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws NoAccessException {
             assert(!method.isStatic());
             Class<?> defc = method.getDeclaringClass();  // receiver type of mh is too wide
             if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
@@ -898,11 +916,16 @@
      * @return a method handle which always invokes the call site's target
      */
     public static
-    MethodHandle dynamicInvoker(CallSite site) {
+    MethodHandle dynamicInvoker(CallSite site) throws NoAccessException {
         MethodHandle getCSTarget = GET_TARGET;
-        if (getCSTarget == null)
-            GET_TARGET = getCSTarget = Lookup.IMPL_LOOKUP.
-                findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
+        if (getCSTarget == null) {
+            try {
+                GET_TARGET = getCSTarget = Lookup.IMPL_LOOKUP.
+                    findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
+            } catch (NoAccessException ex) {
+                throw new InternalError();
+            }
+        }
         MethodHandle getTarget = MethodHandleImpl.bindReceiver(IMPL_TOKEN, getCSTarget, site);
         MethodHandle invoker = exactInvoker(site.type());
         return foldArguments(invoker, getTarget);
@@ -1260,17 +1283,20 @@
      * <p>
      * <b>Example:</b>
      * <p><blockquote><pre>
-     *   MethodHandle cat = MethodHandles.lookup().
-     *     findVirtual(String.class, "concat", String.class, String.class);
-     *   System.out.println(cat.&lt;String&gt;invokeExact("x", "y")); // xy
+     *   import static java.dyn.MethodHandles.*;
+     *   import static java.dyn.MethodType.*;
+     *   ...
+     *   MethodHandle cat = lookup().findVirtual(String.class,
+     *     "concat", methodType(String.class, String.class));
+     *   System.out.println((String) cat.invokeExact("x", "y")); // xy
      *   MethodHandle d0 = dropArguments(cat, 0, String.class);
-     *   System.out.println(d0.&lt;String&gt;invokeExact("x", "y", "z")); // xy
+     *   System.out.println((String) d0.invokeExact("x", "y", "z")); // yz
      *   MethodHandle d1 = dropArguments(cat, 1, String.class);
-     *   System.out.println(d1.&lt;String&gt;invokeExact("x", "y", "z")); // xz
+     *   System.out.println((String) d1.invokeExact("x", "y", "z")); // xz
      *   MethodHandle d2 = dropArguments(cat, 2, String.class);
-     *   System.out.println(d2.&lt;String&gt;invokeExact("x", "y", "z")); // yz
-     *   MethodHandle d12 = dropArguments(cat, 1, String.class, String.class);
-     *   System.out.println(d12.&lt;String&gt;invokeExact("w", "x", "y", "z")); // wz
+     *   System.out.println((String) d2.invokeExact("x", "y", "z")); // xy
+     *   MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
+     *   System.out.println((String) d12.invokeExact("x", 12, true, "z")); // xz
      * </pre></blockquote>
      * @param target the method handle to invoke after the argument is dropped
      * @param valueTypes the type(s) of the argument to drop
@@ -1562,4 +1588,107 @@
     MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
         return MethodHandleImpl.throwException(IMPL_TOKEN, MethodType.methodType(returnType, exType));
     }
+
+    /**
+     * Produce a wrapper instance of the given "SAM" type which redirects its calls to the given method handle.
+     * A SAM type is a type which declares a single abstract method.
+     * Additionally, it must have either no constructor (as an interface)
+     * or have a public or protected constructor of zero arguments (as a class).
+     * <p>
+     * The resulting instance of the required SAM type will respond to
+     * invocation of the SAM type's single abstract method by calling
+     * 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.invokeExact}.
+     * <p>
+     * The method handle may throw an <em>undeclared exception</em>,
+     * which means any checked exception (or other checked throwable)
+     * not declared by the SAM type's single abstract method.
+     * If this happens, the throwable will be wrapped in an instance
+     * of {@link UndeclaredThrowableException} and thrown in that
+     * wrapped form.
+     * <p>
+     * The wrapper instance is guaranteed to be of a non-public
+     * implementation class C in a package containing no classes
+     * or methods except system-defined classes and methods.
+     * The implementation class C will have no public supertypes
+     * or public methods beyond the following:
+     * <ul>
+     * <li>the SAM type itself and any methods in the SAM type
+     * <li>the supertypes of the SAM type (if any) and their methods
+     * <li>{@link Object} and its methods
+     * <li>{@link MethodHandleProvider} and its methods
+     * </ul>
+     * <p>
+     * No stable mapping is promised between the SAM type and
+     * the implementation class C.  Over time, several implementation
+     * classes might be used for the same SAM type.
+     * <p>
+     * This method is not guaranteed to return a distinct
+     * wrapper object for each separate call.  If the JVM is able
+     * to prove that a wrapper has already been created for a given
+     * method handle, or for another method handle with the
+     * same behavior, the JVM may return that wrapper in place of
+     * a new wrapper.
+     * @param target the method handle to invoke from the wrapper
+     * @param samType the desired type of the wrapper, a SAM type
+     * @return a correctly-typed wrapper for the given {@code target}
+     * @throws IllegalArgumentException if the {@code target} throws
+     *         an undeclared exception
+     */
+    // ISSUE: Should we delegate equals/hashCode to the targets?
+    // Not useful unless there is a stable equals/hashCode behavior
+    // for MethodHandle, and for MethodHandleProvider.asMethodHandle.
+    public static
+    <T> T asInstance(MethodHandle target, Class<T> samType) {
+        // POC implementation only; violates the above contract several ways
+        final Method sam = getSamMethod(samType);
+        if (sam == null)
+            throw new IllegalArgumentException("not a SAM type: "+samType.getName());
+        MethodType samMT = MethodType.methodType(sam.getReturnType(), sam.getParameterTypes());
+        if (!samMT.equals(target.type()))
+            throw new IllegalArgumentException("wrong method type");
+        final MethodHandle mh = target;
+        return samType.cast(Proxy.newProxyInstance(
+                samType.getClassLoader(),
+                new Class[]{ samType, MethodHandleProvider.class },
+                new InvocationHandler() {
+                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                        if (method.getDeclaringClass() == MethodHandleProvider.class) {
+                            return method.invoke(mh, args);
+                        }
+                        assert method.equals(sam) : method;
+                        return mh.invokeVarargs(args);
+                    }
+                }));
+    }
+
+    private static
+    Method getSamMethod(Class<?> samType) {
+        Method sam = null;
+        for (Method m : samType.getMethods()) {
+            int mod = m.getModifiers();
+            if (Modifier.isAbstract(mod)) {
+                if (sam != null)
+                    return null;  // too many abstract methods
+                sam = m;
+            }
+        }
+        if (!samType.isInterface() && getSamConstructor(samType) == null)
+            return null;  // wrong kind of constructor
+        return sam;
+    }
+
+    private static
+    Constructor getSamConstructor(Class<?> samType) {
+        for (Constructor c : samType.getDeclaredConstructors()) {
+            if (c.getParameterTypes().length == 0) {
+                int mod = c.getModifiers();
+                if (Modifier.isPublic(mod) || Modifier.isProtected(mod))
+                    return c;
+            }
+        }
+        return null;
+    }
 }
--- a/src/share/classes/java/dyn/MethodType.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/MethodType.java	Thu Nov 11 18:46:02 2010 -0800
@@ -40,24 +40,37 @@
  * returned by a method handle, or the arguments and return type passed
  * and expected  by a method handle caller.  Method types must be properly
  * matched between a method handle and all its callers,
- * and the JVM's operations enforce this matching at all times.
+ * and the JVM's operations enforce this matching at, specifically
+ * during calls to {@link MethodHandle#invokeExact}
+ * and {@link MethodHandle#invokeGeneric}, and during execution
+ * of {@code invokedynamic} instructions.
  * <p>
  * The structure is a return type accompanied by any number of parameter types.
- * The types (primitive, void, and reference) are represented by Class objects.
+ * The types (primitive, {@code void}, and reference) are represented by {@link Class} objects.
+ * (For ease of exposition, we treat {@code void} as if it were a type.
+ * In fact, it denotes the absence of a return type.)
  * <p>
- * All instances of <code>MethodType</code> are immutable.
+ * All instances of {@code MethodType} are immutable.
  * Two instances are completely interchangeable if they compare equal.
  * Equality depends on pairwise correspondence of the return and parameter types and on nothing else.
  * <p>
  * This type can be created only by factory methods.
  * All factory methods may cache values, though caching is not guaranteed.
  * <p>
- * Note: Like classes and strings, method types can be represented directly
- * as constants to be loaded by {@code ldc} bytecodes.
+ * {@code MethodType} objects are sometimes derived from bytecode instructions
+ * such as {@code invokedynamic}, specifically from the type descriptor strings associated
+ * with the instructions in a class file's constant pool.
+ * When this occurs, any classes named in the descriptor strings must be loaded.
+ * (But they need not be initialized.)
+ * This loading may occur at any time before the {@code MethodType} object is first derived.
+ * <p>
+ * Like classes and strings, method types can be represented directly
+ * in a class file's constant pool as constants to be loaded by {@code ldc} bytecodes.
+ * Loading such a constant causes its component classes to be loaded as necessary.
  * @author John Rose, JSR 292 EG
  */
 public final
-class MethodType {
+class MethodType implements java.lang.reflect.Type {
     private final Class<?>   rtype;
     private final Class<?>[] ptypes;
     private MethodTypeForm form; // erased form, plus cached data about primitives
@@ -636,11 +649,11 @@
 
     /** Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[])}.
      * Find or create an instance of the given method type.
-     * Any class or interface name embedded in the signature string
+     * Any class or interface name embedded in the descriptor string
      * will be resolved by calling {@link ClassLoader#loadClass(java.lang.String)}
      * on the given loader (or if it is null, on the system class loader).
      * <p>
-     * Note that it is possible to build method types which cannot be
+     * Note that it is possible to encounter method types which cannot be
      * constructed by this method, because their component types are
      * not all reachable from a common class loader.
      * <p>
@@ -662,8 +675,11 @@
     }
 
     /**
-     * Create a bytecode signature representation of the type.
-     * Note that this is not a strict inverse of
+     * Create a bytecode descriptor representation of the method type.
+     * <p>
+     * Note that this is not a strict inverse of {@link #fromMethodDescriptorString}.
+     * Two distinct classes which share a common name but have different class loaders
+     * will appear identical when viewed within descriptor strings.
      * <p>
      * This method is included for the benfit of applications that must
      * generate bytecodes that process method handles and invokedynamic.
--- a/src/share/classes/java/dyn/NoAccessException.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/NoAccessException.java	Thu Nov 11 18:46:02 2010 -0800
@@ -37,7 +37,7 @@
  * @author John Rose, JSR 292 EG
  * @since 1.7
  */
-public class NoAccessException extends RuntimeException {
+public class NoAccessException extends ReflectiveOperationException {
     private static final long serialVersionUID = 292L;
 
     /**
--- a/src/share/classes/java/dyn/package-info.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/dyn/package-info.java	Thu Nov 11 18:46:02 2010 -0800
@@ -40,20 +40,18 @@
  * The JVM links any such call (regardless of signature) to a dynamically
  * typed method handle invocation.  In the case of {@code invokeGeneric},
  * argument and return value conversions are applied.
+ * </li>
  *
- * <li>In source code, the class {@link java.dyn.InvokeDynamic} appears to accept
+ * <li>In source code, the class {@link java.dyn.InvokeDynamic InvokeDynamic} appears to accept
  * any static method invocation, of any name and any signature.
  * But instead of emitting
  * an {@code invokestatic} instruction for such a call, the Java compiler emits
  * an {@code invokedynamic} instruction with the given name and signature.
- *
- * <li>When the JVM links an {@code invokedynamic} instruction, it calls the
- * {@linkplain java.dyn.Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
- * of the containing class to obtain a {@linkplain java.dyn.CallSite call site} object through which
- * the call site will link its target {@linkplain java.dyn.MethodHandle method handle}.
+ * </li>
  *
  * <li>The JVM bytecode format supports immediate constants of
- * the classes {@link java.dyn.MethodHandle} and {@link java.dyn.MethodType}.
+ * the classes {@link java.dyn.MethodHandle MethodHandle} and {@link java.dyn.MethodType MethodType}.
+ * </li>
  * </ul>
  *
  * <h2><a name="jvm_mods"></a>Corresponding JVM bytecode format changes</h2>
@@ -65,18 +63,50 @@
  * The first byte is the opcode 186 (hexadecimal {@code BA}).
  * The next two bytes are a constant pool index (in the same format as for the other {@code invoke} instructions).
  * The final two bytes are reserved for future use and required to be zero.
- * The constant pool reference is to a entry with tag {@code CONSTANT_NameAndType}
- * (decimal 12).  It is thus not a method reference of any sort, but merely
- * the method name, argument types, and return type of the dynamic call site.
- * <em>(TBD: The EG is discussing the possibility of a special constant pool entry type,
- * so that other information may be added, such as a per-instruction bootstrap
- * method and/or annotations.)</em>
+ * The constant pool reference of an {@code invokedynamic} instruction is to a entry
+ * with tag {@code CONSTANT_InvokeDynamic} (decimal 17).  See below for its format.
+ * The entry specifies the bootstrap method (a {@link java.dyn.MethodHandle MethodHandle} constant),
+ * the dynamic invocation name, and the argument types and return type of the call.
+ * <p>
+ * Each instance of an {@code invokedynamic} instruction is called a <em>dynamic call site</em>.
+ * Multiple instances of an {@code invokedynamic} instruction can share a single
+ * {@code CONSTANT_InvokeDynamic} entry.
+ * In any case, distinct call sites always have distinct linkage state.
+ * <p>
+ * Moreover, for the purpose of distinguishing dynamic call sites,
+ * the JVM is allowed (but not required) to make internal copies
+ * of {@code invokedynamic} instructions, each one
+ * constituting a separate dynamic call site with its own linkage state.
+ * Such copying, if it occurs, cannot be observed except indirectly via
+ * execution of bootstrap methods and target methods.
+ * <p>
+ * A dynamic call site is originally in an unlinked state.  In this state, there is
+ * no target method for the call site to invoke.
+ * A dynamic call site is linked by means of a bootstrap method,
+ * as <a href="#bsm">described below</a>.
+ * <p>
+ * <em>(Historic Note: Some older JVMs may allow the index of a {@code CONSTANT_NameAndType}
+ * instead of a {@code CONSTANT_InvokeDynamic}.  In earlier, obsolete versions of this API, the
+ * bootstrap method was specified dynamically, in a per-class basis, during class initialization.)</em>
+ *
+ * <h3>constant pool entries for {@code invokedynamic} instructions</h3>
+ * If a constant pool entry has the tag {@code CONSTANT_InvokeDynamic} (decimal 17),
+ * it must contain exactly four more bytes.
+ * The first two bytes after the tag must be an index to a {@code CONSTANT_MethodHandle}
+ * entry, and the second two bytes must be an index to a {@code CONSTANT_NameAndType}.
+ * The first index specifies a bootstrap method used by the associated dynamic call sites.
+ * The second index specifies the method name, argument types, and return type of the dynamic call site.
+ * The structure of such an entry is therefore analogous to a {@code CONSTANT_Methodref},
+ * except that the {@code CONSTANT_Class} reference in a {@code CONSTANT_Methodref} entry
+ * is replaced by a bootstrap method reference.
  *
  * <h3>constant pool entries for {@code MethodType}s</h3>
  * If a constant pool entry has the tag {@code CONSTANT_MethodType} (decimal 16),
- * it must contain exactly two more bytes, which are an index to a {@code CONSTANT_Utf8}
- * entry which represents a method type signature.  The JVM will ensure that on first
- * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType}
+ * it must contain exactly two more bytes, which must be an index to a {@code CONSTANT_Utf8}
+ * entry which represents a method type signature.
+ * <p>
+ * The JVM will ensure that on first
+ * execution of an {@code ldc} instruction for this entry, a {@link java.dyn.MethodType MethodType}
  * will be created which represents the signature.
  * Any classes mentioned in the {@code MethodType} will be loaded if necessary,
  * but not initialized.
@@ -86,12 +116,15 @@
  * <h3>constant pool entries for {@code MethodHandle}s</h3>
  * If a constant pool entry has the tag {@code CONSTANT_MethodHandle} (decimal 15),
  * it must contain exactly three more bytes.  The first byte after the tag is a subtag
- * value in the range 1 through 9, and the last two are an index to a
+ * value which must be in the range 1 through 9, and the last two must be an index to a
  * {@code CONSTANT_Fieldref}, {@code CONSTANT_Methodref}, or
  * {@code CONSTANT_InterfaceMethodref} entry which represents a field or method
  * for which a method handle is to be created.
+ * Furthermore, the subtag value and the type of the constant index value
+ * must agree according to the table below.
+ * <p>
  * The JVM will ensure that on first execution of an {@code ldc} instruction
- * for this entry, a {@link java.dyn.MethodHandle} will be created which represents
+ * for this entry, a {@link java.dyn.MethodHandle MethodHandle} will be created which represents
  * the field or method reference, according to the specific mode implied by the subtag.
  * <p>
  * As with {@code CONSTANT_Class} and {@code CONSTANT_MethodType} constants,
@@ -126,6 +159,129 @@
  * Method handles for subtags {@code REF_getStatic}, {@code REF_putStatic}, and {@code REF_invokeStatic}
  * may force class initialization on their first invocation, just like the corresponding bytecodes.
  *
+ * <h2><a name="bsm"></a>Bootstrap Methods</h2>
+ * Before the JVM can execute a dynamic call site (an {@code invokedynamic} instruction),
+ * the call site must first be <em>linked</em>.
+ * Linking is accomplished by calling a <em>bootstrap method</em>
+ * which is given the static information content of the call site,
+ * and which must produce a {@link java.dyn.MethodHandle method handle}
+ * that gives the behavior of the call site.
+ * <p>
+ * Each {@code invokedynamic} instruction statically specifies its own
+ * bootstrap method as a constant pool reference.
+ * The constant pool reference also specifies the call site's name and type signature,
+ * just like {@code invokevirtual} and the other invoke instructions.
+ * <p>
+ * Linking starts with resolving the constant pool entry for the
+ * bootstrap method, and resolving a {@link java.dyn.MethodType MethodType} object for
+ * the type signature of the dynamic call site.
+ * This resolution process may trigger class loading.
+ * It may therefore throw an error if a class fails to load.
+ * This error becomes the abnormal termination of the dynamic
+ * call site execution.
+ * Linkage does not trigger class initialization.
+ * <p>
+ * Next, the bootstrap method call is started, with four values being stacked:
+ * <ul>
+ * <li>a {@code MethodHandle}, the resolved bootstrap method itself </li>
+ * <li>a {@code Class}, the <em>caller class</em> in which dynamic call site occurs </li>
+ * <li>a {@code String}, the method name mentioned in the call site </li>
+ * <li>a {@code MethodType}, the resolved type signature of the call </li>
+ * </ul>
+ * The method handle is then applied to the other values as if by
+ * {@linkplain java.dyn.MethodHandle#invokeGeneric the <code>invokeGeneric</code> method}.
+ * The returned result must be a {@link java.dyn.CallSite CallSite}, a {@link java.dyn.MethodHandle MethodHandle},
+ * or another {@link java.dyn.MethodHandleProvider MethodHandleProvider} value.
+ * The method {@linkplain java.dyn.MethodHandleProvider#asMethodHandle asMethodHandle}
+ * is then called on the returned value.  The result of that second
+ * call is the {@code MethodHandle} which becomes the
+ * permanent binding for the dynamic call site.
+ * That method handle's type must be exactly equal to the type
+ * derived from the dynamic call site signature and passed to
+ * the bootstrap method.
+ * <p>
+ * After resolution, the linkage process may fail in a variety of ways.
+ * All failures are reported by an {@link java.dyn.InvokeDynamicBootstrapError InvokeDynamicBootstrapError},
+ * which is thrown as the abnormal termination of the dynamic call
+ * site execution.
+ * The following circumstances will cause this:
+ * <ul>
+ * <li>the bootstrap method invocation completes abnormally </li>
+ * <li>the result from the bootstrap invocation is not a reference to
+ *     an object of type {@link java.dyn.MethodHandleProvider MethodHandleProvider} </li>
+ * <li>the call to {@code asMethodHandle} completes abnormally </li>
+ * <li>the call to {@code asMethodHandle} fails to return a reference to
+ *     an object of type {@link java.dyn.MethodHandle MethodHandle} </li>
+ * <li>the method handle produced by {@code asMethodHandle} does not have
+ *     the expected {@code MethodType} </li>
+ * </ul>
+ * <h3>timing of linkage</h3>
+ * A dynamic call site is linked just before its first execution.
+ * The bootstrap method call implementing the linkage occurs within
+ * a thread that is attempting a first execution.
+ * <p>
+ * If there are several such threads, the JVM picks one thread
+ * and runs the bootstrap method while the others wait for the
+ * invocation to terminate normally or abnormally.
+ * <p>
+ * After a bootstrap method is called and a method handle target
+ * successfully extracted, the JVM attempts to link the instruction
+ * being executed to the target method handle.
+ * This may fail if there has been intervening linkage
+ * or invalidation event for the same instruction.
+ * If such a failure occurs, the dynamic call site must be
+ * re-executed from the beginning, either re-linking it
+ * (if it has been invalidated) or invoking the target
+ * (if it the instruction has been linked by some other means).
+ * <p>
+ * If the instruction is linked successfully, the target method
+ * handle is invoked to complete the instruction execution.
+ * The state of linkage continues until the method containing the
+ * dynamic call site is garbage collected, or the dynamic call site
+ * is invalidated by an explicit request,
+ * such as {@link java.dyn.Linkage#invalidateCallerClass Linkage.invalidateCallerClass}.
+ * <p>
+ * In an application which requires dynamic call sites with individually
+ * mutable behaviors, their bootstrap methods should produce distinct
+ * {@link java.dyn.CallSite CallSite} objects, one for each linkage request.
+ * <p>
+ * If a class containing {@code invokedynamic} instructions
+ * is {@linkplain java.dyn.Linkage#invalidateCallerClass(Class) invalidated},
+ * subsequent execution of those {@code invokedynamic} instructions
+ * will require linking.
+ * It is as if they had never been executed in the first place.
+ * (However, invalidation does not cause constant pool entries to be
+ * resolved a second time.)
+ * <p>
+ * Invalidation events and bootstrap method calls for a particular
+ * dynamic call site are globally ordered relative to each other.
+ * When an invokedynamic instruction is invalidated, if there is
+ * simultaneously a bootstrap method invocation in process
+ * (in the same thread or a different thread), the result
+ * eventually returned must not be used to link the call site.
+ * Put another way, when a call site is invalidated, its
+ * subsequent linkage (if any) must be performed by a bootstrap method
+ * call initiated after the invalidation occurred.
+ * <p>
+ * If several threads simultaneously execute a bootstrap method for a single dynamic
+ * call site, the JVM must choose one target object and installs it visibly to
+ * all threads.  Any other bootstrap method calls are allowed to complete, but their
+ * results are ignored, and their dynamic call site invocations proceed with the originally
+ * chosen target object.
+ * <p>
+ * The JVM is free to duplicate dynamic call sites.
+ * This means that, even if a class contains just one {@code invokedynamic}
+ * instruction, its bootstrap method may be executed several times,
+ * once for each duplicate.  Thus, bootstrap method code should not
+ * assume an exclusive one-to-one correspondence between particular occurrences
+ * of {@code invokedynamic} bytecodes in class files and linkage events.
+ * <p>
+ * In principle, each individual execution of an {@code invokedynamic}
+ * instruction could be deemed (by a conforming implementation) to be a separate
+ * duplicate, requiring its own execution of the bootstrap method.
+ * However, implementations are expected to perform code duplication
+ * (if at all) in order to improve performance, not make it worse.
+ *
  * @author John Rose, JSR 292 EG
  */
 
--- a/src/share/classes/java/io/ObjectInputStream.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/io/ObjectInputStream.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -265,7 +265,7 @@
      * object currently being deserialized and descriptor for current class.
      * Null when not during readObject upcall.
      */
-    private CallbackContext curContext;
+    private SerialCallbackContext curContext;
 
     /**
      * Creates an ObjectInputStream that reads from the specified InputStream.
@@ -1798,7 +1798,7 @@
     private void readExternalData(Externalizable obj, ObjectStreamClass desc)
         throws IOException
     {
-        CallbackContext oldContext = curContext;
+        SerialCallbackContext oldContext = curContext;
         curContext = null;
         try {
             boolean blocked = desc.hasBlockExternalData();
@@ -1857,10 +1857,10 @@
                     slotDesc.hasReadObjectMethod() &&
                     handles.lookupException(passHandle) == null)
                 {
-                    CallbackContext oldContext = curContext;
+                    SerialCallbackContext oldContext = curContext;
 
                     try {
-                        curContext = new CallbackContext(obj, slotDesc);
+                        curContext = new SerialCallbackContext(obj, slotDesc);
 
                         bin.setBlockDataMode(true);
                         slotDesc.invokeReadObject(obj, this);
@@ -3505,42 +3505,4 @@
         }
     }
 
-    /**
-     * Context that during upcalls to class-defined readObject methods; holds
-     * object currently being deserialized and descriptor for current class.
-     * This context keeps a boolean state to indicate that defaultReadObject
-     * or readFields has already been invoked with this context or the class's
-     * readObject method has returned; if true, the getObj method throws
-     * NotActiveException.
-     */
-    private static class CallbackContext {
-        private final Object obj;
-        private final ObjectStreamClass desc;
-        private final AtomicBoolean used = new AtomicBoolean();
-
-        public CallbackContext(Object obj, ObjectStreamClass desc) {
-            this.obj = obj;
-            this.desc = desc;
-        }
-
-        public Object getObj() throws NotActiveException {
-            checkAndSetUsed();
-            return obj;
-        }
-
-        public ObjectStreamClass getDesc() {
-            return desc;
-        }
-
-        private void checkAndSetUsed() throws NotActiveException {
-            if (!used.compareAndSet(false, true)) {
-                 throw new NotActiveException(
-                      "not in readObject invocation or fields already read");
-            }
-        }
-
-        public void setUsed() {
-            used.set(true);
-        }
-    }
 }
--- a/src/share/classes/java/io/ObjectOutputStream.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/io/ObjectOutputStream.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import static java.io.ObjectStreamClass.processQueue;
+import java.io.SerialCallbackContext;
 
 /**
  * An ObjectOutputStream writes primitive data types and graphs of Java objects
@@ -191,10 +192,12 @@
     private boolean enableReplace;
 
     // values below valid only during upcalls to writeObject()/writeExternal()
-    /** object currently being serialized */
-    private Object curObj;
-    /** descriptor for current class (null if in writeExternal()) */
-    private ObjectStreamClass curDesc;
+    /**
+     * Context during upcalls to class-defined writeObject methods; holds
+     * object currently being serialized and descriptor for current class.
+     * Null when not during writeObject upcall.
+     */
+    private SerialCallbackContext curContext;
     /** current PutField object */
     private PutFieldImpl curPut;
 
@@ -426,9 +429,11 @@
      *          <code>OutputStream</code>
      */
     public void defaultWriteObject() throws IOException {
-        if (curObj == null || curDesc == null) {
+        if ( curContext == null ) {
             throw new NotActiveException("not in call to writeObject");
         }
+        Object curObj = curContext.getObj();
+        ObjectStreamClass curDesc = curContext.getDesc();
         bout.setBlockDataMode(false);
         defaultWriteFields(curObj, curDesc);
         bout.setBlockDataMode(true);
@@ -446,9 +451,11 @@
      */
     public ObjectOutputStream.PutField putFields() throws IOException {
         if (curPut == null) {
-            if (curObj == null || curDesc == null) {
+            if (curContext == null) {
                 throw new NotActiveException("not in call to writeObject");
             }
+            Object curObj = curContext.getObj();
+            ObjectStreamClass curDesc = curContext.getDesc();
             curPut = new PutFieldImpl(curDesc);
         }
         return curPut;
@@ -1420,17 +1427,15 @@
      * writeExternal() method.
      */
     private void writeExternalData(Externalizable obj) throws IOException {
-        Object oldObj = curObj;
-        ObjectStreamClass oldDesc = curDesc;
         PutFieldImpl oldPut = curPut;
-        curObj = obj;
-        curDesc = null;
         curPut = null;
 
         if (extendedDebugInfo) {
             debugInfoStack.push("writeExternal data");
         }
+        SerialCallbackContext oldContext = curContext;
         try {
+            curContext = null;
             if (protocol == PROTOCOL_VERSION_1) {
                 obj.writeExternal(this);
             } else {
@@ -1440,13 +1445,12 @@
                 bout.writeByte(TC_ENDBLOCKDATA);
             }
         } finally {
+            curContext = oldContext;
             if (extendedDebugInfo) {
                 debugInfoStack.pop();
             }
         }
 
-        curObj = oldObj;
-        curDesc = oldDesc;
         curPut = oldPut;
     }
 
@@ -1461,12 +1465,9 @@
         for (int i = 0; i < slots.length; i++) {
             ObjectStreamClass slotDesc = slots[i].desc;
             if (slotDesc.hasWriteObjectMethod()) {
-                Object oldObj = curObj;
-                ObjectStreamClass oldDesc = curDesc;
                 PutFieldImpl oldPut = curPut;
-                curObj = obj;
-                curDesc = slotDesc;
                 curPut = null;
+                SerialCallbackContext oldContext = curContext;
 
                 if (extendedDebugInfo) {
                     debugInfoStack.push(
@@ -1474,18 +1475,19 @@
                         slotDesc.getName() + "\")");
                 }
                 try {
+                    curContext = new SerialCallbackContext(obj, slotDesc);
                     bout.setBlockDataMode(true);
                     slotDesc.invokeWriteObject(obj, this);
                     bout.setBlockDataMode(false);
                     bout.writeByte(TC_ENDBLOCKDATA);
                 } finally {
+                    curContext.setUsed();
+                    curContext = oldContext;
                     if (extendedDebugInfo) {
                         debugInfoStack.pop();
                     }
                 }
 
-                curObj = oldObj;
-                curDesc = oldDesc;
                 curPut = oldPut;
             } else {
                 defaultWriteFields(obj, slotDesc);
--- a/src/share/classes/java/io/ObjectStreamClass.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/io/ObjectStreamClass.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1830,8 +1830,10 @@
         private final ObjectStreamField[] fields;
         /** number of primitive fields */
         private final int numPrimFields;
-        /** unsafe field keys */
-        private final long[] keys;
+        /** unsafe field keys for reading fields - may contain dupes */
+        private final long[] readKeys;
+        /** unsafe fields keys for writing fields - no dupes */
+        private final long[] writeKeys;
         /** field data offsets */
         private final int[] offsets;
         /** field type codes */
@@ -1849,16 +1851,22 @@
         FieldReflector(ObjectStreamField[] fields) {
             this.fields = fields;
             int nfields = fields.length;
-            keys = new long[nfields];
+            readKeys = new long[nfields];
+            writeKeys = new long[nfields];
             offsets = new int[nfields];
             typeCodes = new char[nfields];
             ArrayList<Class<?>> typeList = new ArrayList<Class<?>>();
+            Set<Long> usedKeys = new HashSet<Long>();
+
 
             for (int i = 0; i < nfields; i++) {
                 ObjectStreamField f = fields[i];
                 Field rf = f.getField();
-                keys[i] = (rf != null) ?
+                long key = (rf != null) ?
                     unsafe.objectFieldOffset(rf) : Unsafe.INVALID_FIELD_OFFSET;
+                readKeys[i] = key;
+                writeKeys[i] = usedKeys.add(key) ?
+                    key : Unsafe.INVALID_FIELD_OFFSET;
                 offsets[i] = f.getOffset();
                 typeCodes[i] = f.getTypeCode();
                 if (!f.isPrimitive()) {
@@ -1894,7 +1902,7 @@
              * in array should be equal to Unsafe.INVALID_FIELD_OFFSET.
              */
             for (int i = 0; i < numPrimFields; i++) {
-                long key = keys[i];
+                long key = readKeys[i];
                 int off = offsets[i];
                 switch (typeCodes[i]) {
                     case 'Z':
@@ -1945,7 +1953,7 @@
                 throw new NullPointerException();
             }
             for (int i = 0; i < numPrimFields; i++) {
-                long key = keys[i];
+                long key = writeKeys[i];
                 if (key == Unsafe.INVALID_FIELD_OFFSET) {
                     continue;           // discard value
                 }
@@ -2006,7 +2014,7 @@
                 switch (typeCodes[i]) {
                     case 'L':
                     case '[':
-                        vals[offsets[i]] = unsafe.getObject(obj, keys[i]);
+                        vals[offsets[i]] = unsafe.getObject(obj, readKeys[i]);
                         break;
 
                     default:
@@ -2027,7 +2035,7 @@
                 throw new NullPointerException();
             }
             for (int i = numPrimFields; i < fields.length; i++) {
-                long key = keys[i];
+                long key = writeKeys[i];
                 if (key == Unsafe.INVALID_FIELD_OFFSET) {
                     continue;           // discard value
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/io/SerialCallbackContext.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,58 @@
+  /*
+   * %W% %E%
+   *
+   * Copyright (c) 2006, 2010  Oracle and/or its affiliates. All rights reserved.
+   * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+   */
+
+  package java.io;
+
+  /**
+   * Context during upcalls from object stream to class-defined
+   * readObject/writeObject methods.
+   * Holds object currently being deserialized and descriptor for current class.
+   *
+   * This context keeps track of the thread it was constructed on, and allows
+   * only a single call of defaultReadObject, readFields, defaultWriteObject
+   * or writeFields which must be invoked on the same thread before the class's
+   * readObject/writeObject method has returned.
+   * If not set to the current thread, the getObj method throws NotActiveException.
+   */
+  final class SerialCallbackContext {
+      private final Object obj;
+      private final ObjectStreamClass desc;
+      /**
+       * Thread this context is in use by.
+       * As this only works in one thread, we do not need to worry about thread-safety.
+       */
+      private Thread thread;
+
+      public SerialCallbackContext(Object obj, ObjectStreamClass desc) {
+          this.obj = obj;
+          this.desc = desc;
+          this.thread = Thread.currentThread();
+      }
+
+      public Object getObj() throws NotActiveException {
+          checkAndSetUsed();
+          return obj;
+      }
+
+      public ObjectStreamClass getDesc() {
+          return desc;
+      }
+
+      private void checkAndSetUsed() throws NotActiveException {
+          if (thread != Thread.currentThread()) {
+               throw new NotActiveException(
+                "not in readObject invocation or fields already read");
+          }
+          thread = null;
+      }
+
+      public void setUsed() {
+          thread = null;
+      }
+  }
+
+
--- a/src/share/classes/java/lang/AbstractStringBuilder.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/lang/AbstractStringBuilder.java	Thu Nov 11 18:46:02 2010 -0800
@@ -100,7 +100,8 @@
      * @param   minimumCapacity   the minimum desired capacity.
      */
     public void ensureCapacity(int minimumCapacity) {
-        ensureCapacityInternal(minimumCapacity);
+        if (minimumCapacity > 0)
+            ensureCapacityInternal(minimumCapacity);
     }
 
     /**
@@ -108,6 +109,7 @@
      * never synchronized.
      */
     private void ensureCapacityInternal(int minimumCapacity) {
+        // overflow-conscious code
         if (minimumCapacity - value.length > 0)
             expandCapacity(minimumCapacity);
     }
--- a/src/share/classes/java/lang/ClassLoader.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/lang/ClassLoader.java	Thu Nov 11 18:46:02 2010 -0800
@@ -553,6 +553,13 @@
      *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
      *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
      *
+     * @throws  SecurityException
+     *          If an attempt is made to add this class to a package that
+     *          contains classes that were signed by a different set of
+     *          certificates than this class, or if an attempt is made
+     *          to define a class in a package with a fully-qualified name
+     *          that starts with "{@code java.}".
+     *
      * @see  #loadClass(String, boolean)
      * @see  #resolveClass(Class)
      *
--- a/src/share/classes/java/net/AbstractPlainSocketImpl.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/net/AbstractPlainSocketImpl.java	Thu Nov 11 18:46:02 2010 -0800
@@ -28,9 +28,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.InterruptedIOException;
 import java.io.FileDescriptor;
-import java.io.ByteArrayOutputStream;
 
 import sun.net.ConnectionResetException;
 import sun.net.NetHooks;
@@ -58,7 +56,7 @@
     protected int fdUseCount = 0;
 
     /* lock when increment/decrementing fdUseCount */
-    protected Object fdLock = new Object();
+    protected final Object fdLock = new Object();
 
     /* indicates a close is pending on the file descriptor */
     protected boolean closePending = false;
@@ -68,7 +66,7 @@
     private int CONNECTION_RESET_PENDING = 1;
     private int CONNECTION_RESET = 2;
     private int resetState;
-    private Object resetLock = new Object();
+    private final Object resetLock = new Object();
 
     /**
      * Load net library into runtime.
@@ -100,25 +98,24 @@
     protected void connect(String host, int port)
         throws UnknownHostException, IOException
     {
-        IOException pending = null;
+        boolean connected = false;
         try {
             InetAddress address = InetAddress.getByName(host);
             this.port = port;
             this.address = address;
 
-            try {
-                connectToAddress(address, port, timeout);
-                return;
-            } catch (IOException e) {
-                pending = e;
+            connectToAddress(address, port, timeout);
+            connected = true;
+        } finally {
+            if (!connected) {
+                try {
+                    close();
+                } catch (IOException ioe) {
+                    /* Do nothing. If connect threw an exception then
+                       it will be passed up the call stack */
+                }
             }
-        } catch (UnknownHostException e) {
-            pending = e;
         }
-
-        // everything failed
-        close();
-        throw pending;
     }
 
     /**
@@ -151,22 +148,29 @@
      *          SocketAddress subclass not supported by this socket
      * @since 1.4
      */
-    protected void connect(SocketAddress address, int timeout) throws IOException {
-        if (address == null || !(address instanceof InetSocketAddress))
-            throw new IllegalArgumentException("unsupported address type");
-        InetSocketAddress addr = (InetSocketAddress) address;
-        if (addr.isUnresolved())
-            throw new UnknownHostException(addr.getHostName());
-        this.port = addr.getPort();
-        this.address = addr.getAddress();
+    protected void connect(SocketAddress address, int timeout)
+            throws IOException {
+        boolean connected = false;
+        try {
+            if (address == null || !(address instanceof InetSocketAddress))
+                throw new IllegalArgumentException("unsupported address type");
+            InetSocketAddress addr = (InetSocketAddress) address;
+            if (addr.isUnresolved())
+                throw new UnknownHostException(addr.getHostName());
+            this.port = addr.getPort();
+            this.address = addr.getAddress();
 
-        try {
             connectToAddress(this.address, port, timeout);
-            return;
-        } catch (IOException e) {
-            // everything failed
-            close();
-            throw e;
+            connected = true;
+        } finally {
+            if (!connected) {
+                try {
+                    close();
+                } catch (IOException ioe) {
+                    /* Do nothing. If connect threw an exception then
+                       it will be passed up the call stack */
+                }
+            }
         }
     }
 
@@ -311,7 +315,7 @@
             }
         }
         try {
-            FileDescriptor fd = acquireFD();
+            acquireFD();
             try {
                 socketConnect(address, port, timeout);
                 /* socket may have been closed during poll/select */
@@ -370,7 +374,7 @@
      * @param s the connection
      */
     protected void accept(SocketImpl s) throws IOException {
-        FileDescriptor fd = acquireFD();
+        acquireFD();
         try {
             socketAccept(s);
         } finally {
@@ -562,7 +566,6 @@
         close();
     }
 
-
     /*
      * "Acquires" and returns the FileDescriptor for this impl
      *
--- a/src/share/classes/java/nio/Direct-X-Buffer.java.template	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/nio/Direct-X-Buffer.java.template	Thu Nov 11 18:46:02 2010 -0800
@@ -27,6 +27,7 @@
 
 package java.nio;
 
+import java.io.FileDescriptor;
 import sun.misc.Cleaner;
 import sun.misc.Unsafe;
 import sun.misc.VM;
@@ -114,7 +115,7 @@
     //
     Direct$Type$Buffer$RW$(int cap) {                   // package-private
 #if[rw]
-        super(-1, 0, cap, cap, false);
+        super(-1, 0, cap, cap);
         boolean pa = VM.isDirectMemoryPageAligned();
         int ps = Bits.pageSize();
         long size = Math.max(1L, (long)cap + (pa ? ps : 0));
@@ -145,7 +146,7 @@
     // Invoked only by JNI: NewDirectByteBuffer(void*, long)
     //
     private Direct$Type$Buffer(long addr, int cap) {
-        super(-1, 0, cap, cap, false);
+        super(-1, 0, cap, cap);
         address = addr;
         cleaner = null;
     }
@@ -154,14 +155,17 @@
 
     // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
     //
-    protected Direct$Type$Buffer$RW$(int cap, long addr, Runnable unmapper) {
+    protected Direct$Type$Buffer$RW$(int cap, long addr,
+                                     FileDescriptor fd,
+                                     Runnable unmapper)
+    {
 #if[rw]
-        super(-1, 0, cap, cap, true);
+        super(-1, 0, cap, cap, fd);
         address = addr;
         viewedBuffer = null;
         cleaner = Cleaner.create(this, unmapper);
 #else[rw]
-        super(cap, addr, unmapper);
+        super(cap, addr, fd, unmapper);
 #end[rw]
     }
 
--- a/src/share/classes/java/nio/MappedByteBuffer.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/nio/MappedByteBuffer.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,6 +25,7 @@
 
 package java.nio;
 
+import java.io.FileDescriptor;
 import sun.misc.Unsafe;
 
 
@@ -71,26 +72,26 @@
     // for optimization purposes, it's easier to do it the other way around.
     // This works because DirectByteBuffer is a package-private class.
 
-    // Volatile to make sure that the finalization thread sees the current
-    // value of this so that a region is not accidentally unmapped again later.
-    volatile boolean isAMappedBuffer;                   // package-private
+    // For mapped buffers, a FileDescriptor that may be used for mapping
+    // operations if valid; null if the buffer is not mapped.
+    private final FileDescriptor fd;
 
     // This should only be invoked by the DirectByteBuffer constructors
     //
     MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
-                     boolean mapped)
+                     FileDescriptor fd)
     {
         super(mark, pos, lim, cap);
-        isAMappedBuffer = mapped;
+        this.fd = fd;
     }
 
     MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
         super(mark, pos, lim, cap);
-        isAMappedBuffer = false;
+        this.fd = null;
     }
 
     private void checkMapped() {
-        if (!isAMappedBuffer)
+        if (fd == null)
             // Can only happen if a luser explicitly casts a direct byte buffer
             throw new UnsupportedOperationException();
     }
@@ -191,13 +192,12 @@
         checkMapped();
         if ((address != 0) && (capacity() != 0)) {
             long offset = mappingOffset();
-            force0(mappingAddress(offset), mappingLength(offset));
+            force0(fd, mappingAddress(offset), mappingLength(offset));
         }
         return this;
     }
 
     private native boolean isLoaded0(long address, long length, int pageCount);
     private native void load0(long address, long length);
-    private native void force0(long address, long length);
-
+    private native void force0(FileDescriptor fd, long address, long length);
 }
--- a/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java	Tue Nov 02 22:15:35 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,572 +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.channels;
-
-import java.nio.channels.spi.*;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.Future;
-import java.io.IOException;
-import java.net.SocketOption;
-import java.net.SocketAddress;
-import java.net.ProtocolFamily;
-import java.nio.ByteBuffer;
-
-/**
- * An asynchronous channel for datagram-oriented sockets.
- *
- * <p> An asynchronous datagram channel is created by invoking one of the {@link
- * #open open} methods defined by this class. It is not possible to create a channel
- * for an arbitrary, pre-existing datagram socket. A newly-created asynchronous
- * datagram channel is open but not connected. It need not be connected in order
- * for the {@link #send send} and {@link #receive receive} methods to be used.
- * A datagram channel may be connected, by invoking its {@link #connect connect}
- * method, in order to avoid the overhead of the security checks that are otherwise
- * performed as part of every send and receive operation when a security manager
- * is set. The channel must be connected in order to use the {@link #read read}
- * and {@link #write write} methods, since those methods do not accept or return
- * socket addresses. Once connected, an asynchronous datagram channel remains
- * connected until it is disconnected or closed.
- *
- * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
- * setOption} method. An asynchronous datagram channel to an Internet Protocol
- * (IP) socket supports the following options:
- * <blockquote>
- * <table border>
- *   <tr>
- *     <th>Option Name</th>
- *     <th>Description</th>
- *   </tr>
- *   <tr>
- *     <td> {@link java.net.StandardSocketOption#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> The size of the socket receive buffer </td>
- *   </tr>
- *   <tr>
- *     <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
- *     <td> Re-use address </td>
- *   </tr>
- *   <tr>
- *     <td> {@link java.net.StandardSocketOption#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> 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> The network interface for Internet Protocol (IP) multicast datagrams </td>
- *   </tr>
- *   <tr>
- *     <td> {@link java.net.StandardSocketOption#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
- *       IP_MULTICAST_LOOP} </td>
- *     <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
- *   </tr>
- * </table>
- * </blockquote>
- * Additional (implementation specific) options may also be supported.
- *
- * <p> Asynchronous datagram channels allow more than one read/receive and
- * write/send to be oustanding at any given time.
- *
- * <p> <b>Usage Example:</b>
- * <pre>
- *  final AsynchronousDatagramChannel dc = AsynchronousDatagramChannel.open()
- *      .bind(new InetSocketAddress(4000));
- *
- *  // print the source address of all packets that we receive
- *  dc.receive(buffer, buffer, new CompletionHandler&lt;SocketAddress,ByteBuffer&gt;() {
- *      public void completed(SocketAddress sa, ByteBuffer buffer) {
- *          System.out.println(sa);
- *          buffer.clear();
- *          dc.receive(buffer, buffer, this);
- *      }
- *      public void failed(Throwable exc, ByteBuffer buffer) {
- *          ...
- *      }
- *  });
- * </pre>
- *
- * @since 1.7
- */
-
-public abstract class AsynchronousDatagramChannel
-    implements AsynchronousByteChannel, MulticastChannel
-{
-    private final AsynchronousChannelProvider provider;
-
-    /**
-     * Initializes a new instance of this class.
-     */
-    protected AsynchronousDatagramChannel(AsynchronousChannelProvider provider) {
-        this.provider = provider;
-    }
-
-    /**
-     * Returns the provider that created this channel.
-     */
-    public final AsynchronousChannelProvider provider() {
-        return provider;
-    }
-
-    /**
-     * Opens an asynchronous datagram channel.
-     *
-     * <p> The new channel is created by invoking the {@link
-     * java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousDatagramChannel
-     * openAsynchronousDatagramChannel} method on the {@link
-     * java.nio.channels.spi.AsynchronousChannelProvider} object that created
-     * the given group (or the default provider where {@code group} is {@code
-     * null}).
-     *
-     * <p> The {@code family} parameter is used to specify the {@link ProtocolFamily}.
-     * If the datagram channel is to be used for Internet Protocol {@link
-     * MulticastChannel multicasting} then this parameter should correspond to
-     * the address type of the multicast groups that this channel will join.
-     *
-     * @param   family
-     *          The protocol family, or {@code null} to use the default protocol
-     *          family
-     * @param   group
-     *          The group to which the newly constructed channel should be bound,
-     *          or {@code null} for the default group
-     *
-     * @return  A new asynchronous datagram channel
-     *
-     * @throws  UnsupportedOperationException
-     *          If the specified protocol family is not supported. For example,
-     *          suppose the parameter is specified as {@link
-     *          java.net.StandardProtocolFamily#INET6 INET6} but IPv6 is not
-     *          enabled on the platform.
-     * @throws  ShutdownChannelGroupException
-     *          The specified group is shutdown
-     * @throws  IOException
-     *          If an I/O error occurs
-     */
-    public static AsynchronousDatagramChannel open(ProtocolFamily family,
-                                                   AsynchronousChannelGroup group)
-        throws IOException
-    {
-        AsynchronousChannelProvider provider = (group == null) ?
-            AsynchronousChannelProvider.provider() : group.provider();
-        return provider.openAsynchronousDatagramChannel(family, group);
-    }
-
-    /**
-     * Opens an asynchronous datagram channel.
-     *
-     * <p> This method returns an asynchronous datagram channel that is
-     * bound to the <em>default group</em>. This method is equivalent to evaluating
-     * the expression:
-     * <blockquote><pre>
-     * open((ProtocolFamily)null,&nbsp;(AsynchronousChannelGroup)null);
-     * </pre></blockquote>
-     *
-     * @return  A new asynchronous datagram channel
-     *
-     * @throws  IOException
-     *          If an I/O error occurs
-     */
-    public static AsynchronousDatagramChannel open()
-        throws IOException
-    {
-        return open(null, null);
-    }
-
-    // -- Socket-specific operations --
-
-    /**
-     * @throws  AlreadyBoundException               {@inheritDoc}
-     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
-     * @throws  ClosedChannelException              {@inheritDoc}
-     * @throws  IOException                         {@inheritDoc}
-     * @throws  SecurityException
-     *          If a security manager has been installed and its {@link
-     *          SecurityManager#checkListen checkListen} method denies the
-     *          operation
-     */
-    @Override
-    public abstract AsynchronousDatagramChannel bind(SocketAddress local)
-        throws IOException;
-
-    /**
-     * @throws  IllegalArgumentException                {@inheritDoc}
-     * @throws  ClosedChannelException                  {@inheritDoc}
-     * @throws  IOException                             {@inheritDoc}
-     */
-    @Override
-    public abstract <T> AsynchronousDatagramChannel setOption(SocketOption<T> name, T value)
-        throws IOException;
-
-    /**
-     * Returns the remote address to which this channel is connected.
-     *
-     * <p> Where the channel is connected to an Internet Protocol socket address
-     * then the return value from this method is of type {@link
-     * java.net.InetSocketAddress}.
-     *
-     * @return  The remote address; {@code null} if the channel's socket is not
-     *          connected
-     *
-     * @throws  ClosedChannelException
-     *          If the channel is closed
-     * @throws  IOException
-     *          If an I/O error occurs
-     */
-    public abstract SocketAddress getRemoteAddress() throws IOException;
-
-    /**
-     * Connects this channel's socket.
-     *
-     * <p> The channel's socket is configured so that it only receives
-     * datagrams from, and sends datagrams to, the given remote <i>peer</i>
-     * address.  Once connected, datagrams may not be received from or sent to
-     * any other address.  A datagram socket remains connected until it is
-     * explicitly disconnected or until it is closed.
-     *
-     * <p> This method performs exactly the same security checks as the {@link
-     * java.net.DatagramSocket#connect connect} method of the {@link
-     * java.net.DatagramSocket} class.  That is, if a security manager has been
-     * installed then this method verifies that its {@link
-     * java.lang.SecurityManager#checkAccept checkAccept} and {@link
-     * java.lang.SecurityManager#checkConnect checkConnect} methods permit
-     * datagrams to be received from and sent to, respectively, the given
-     * remote address.
-     *
-     * <p> This method may be invoked at any time. Whether it has any effect
-     * on outstanding read or write operations is implementation specific and
-     * therefore not specified.
-     *
-     * @param  remote
-     *         The remote address to which this channel is to be connected
-     *
-     * @return  This datagram channel
-     *
-     * @throws  ClosedChannelException
-     *          If this channel is closed
-     *
-     * @throws  SecurityException
-     *          If a security manager has been installed
-     *          and it does not permit access to the given remote address
-     *
-     * @throws  IOException
-     *          If some other I/O error occurs
-     */
-    public abstract AsynchronousDatagramChannel connect(SocketAddress remote)
-        throws IOException;
-
-    /**
-     * Disconnects this channel's socket.
-     *
-     * <p> The channel's socket is configured so that it can receive datagrams
-     * from, and sends datagrams to, any remote address so long as the security
-     * manager, if installed, permits it.
-     *
-     * <p> This method may be invoked at any time. Whether it has any effect
-     * on outstanding read or write operations is implementation specific and
-     * therefore not specified.
-     *
-     * @return  This datagram channel
-     *
-     * @throws  IOException
-     *          If some other I/O error occurs
-     */
-    public abstract AsynchronousDatagramChannel disconnect() throws IOException;
-
-    /**
-     * Receives a datagram via this channel.
-     *
-     * <p> This method initiates the receiving of a datagram into the given
-     * buffer. The {@code handler} parameter is a completion handler that is
-     * invoked when the receive operation completes (or fails). The result
-     * passed to the completion handler is the datagram's source address.
-     *
-     * <p> The datagram is transferred into the given byte buffer starting at
-     * its current position, as if by a regular {@link AsynchronousByteChannel#read
-     * read} operation. If there are fewer bytes remaining in the buffer
-     * than are required to hold the datagram then the remainder of the datagram
-     * is silently discarded.
-     *
-     * <p> If a timeout is specified and the timeout elapses before the operation
-     * completes then the operation completes with the exception {@link
-     * InterruptedByTimeoutException}. When a timeout elapses then the state of
-     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
-     * at least care must be taken to ensure that the buffer is not accessed
-     * while the channel remains open.
-     *
-     * <p> When a security manager has been installed and the channel is not
-     * connected, then it verifies that the source's address and port number are
-     * permitted by the security manager's {@link SecurityManager#checkAccept
-     * checkAccept} method. The permission check is performed with privileges that
-     * are restricted by the calling context of this method. If the permission
-     * check fails then the operation completes with a {@link SecurityException}.
-     * The overhead of this security check can be avoided by first connecting the
-     * socket via the {@link #connect connect} method.
-     *
-     * @param   dst
-     *          The buffer into which the datagram is to be transferred
-     * @param   timeout
-     *          The timeout, or {@code 0L} for no timeout
-     * @param   unit
-     *          The time unit of the {@code timeout} argument
-     * @param   attachment
-     *          The object to attach to the I/O operation; can be {@code null}
-     * @param   handler
-     *          The handler for consuming the result
-     *
-     * @throws  IllegalArgumentException
-     *          If the timeout is negative or the buffer is read-only
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    public abstract <A> void receive(ByteBuffer dst,
-                                     long timeout,
-                                     TimeUnit unit,
-                                     A attachment,
-                                     CompletionHandler<SocketAddress,? super A> handler);
-
-    /**
-     * Receives a datagram via this channel.
-     *
-     * <p> This method initiates the receiving of a datagram into the given
-     * buffer. The {@code handler} parameter is a completion handler that is
-     * invoked when the receive operation completes (or fails). The result
-     * passed to the completion handler is the datagram's source address.
-     *
-     * <p> This method is equivalent to invoking {@link
-     * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a
-     * timeout of {@code 0L}.
-     *
-     * @param   dst
-     *          The buffer into which the datagram is to be transferred
-     * @param   attachment
-     *          The object to attach to the I/O operation; can be {@code null}
-     * @param   handler
-     *          The handler for consuming the result
-     *
-     * @throws  IllegalArgumentException
-     *          If the buffer is read-only
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    public final <A> void receive(ByteBuffer dst,
-                                  A attachment,
-                                  CompletionHandler<SocketAddress,? super A> handler)
-    {
-        receive(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
-    }
-
-    /**
-     * Receives a datagram via this channel.
-     *
-     * <p> This method initiates the receiving of a datagram into the given
-     * buffer. The method behaves in exactly the same manner as the {@link
-     * #receive(ByteBuffer,Object,CompletionHandler)
-     * receive(ByteBuffer,Object,CompletionHandler)} method except that instead
-     * of specifying a completion handler, this method returns a {@code Future}
-     * representing the pending result. The {@code Future}'s {@link Future#get()
-     * get} method returns the datagram's source address.
-     *
-     * @param   dst
-     *          The buffer into which the datagram is to be transferred
-     *
-     * @return  a {@code Future} object representing the pending result
-     *
-     * @throws  IllegalArgumentException
-     *          If the buffer is read-only
-     */
-    public abstract Future<SocketAddress> receive(ByteBuffer dst);
-
-    /**
-     * Sends a datagram via this channel.
-     *
-     * <p> This method initiates sending of a datagram from the given buffer to
-     * the given address. The {@code handler} parameter is a completion handler
-     * that is invoked when the send completes (or fails). The result passed to
-     * the completion handler is the number of bytes sent.
-     *
-     * <p> Otherwise this method works in the same manner as the {@link
-     * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
-     * method.
-     *
-     * @param   src
-     *          The buffer containing the datagram to be sent
-     * @param   target
-     *          The address to which the datagram is to be sent
-     * @param   attachment
-     *          The object to attach to the I/O operation; can be {@code null}
-     * @param   handler
-     *          The handler for consuming the result
-     *
-     * @throws  UnresolvedAddressException
-     *          If the given remote address is not fully resolved
-     * @throws  UnsupportedAddressTypeException
-     *          If the type of the given remote address is not supported
-     * @throws  IllegalArgumentException
-     *          If the channel's socket is connected and is connected to an
-     *          address that is not equal to {@code target}
-     * @throws  SecurityException
-     *          If a security manager has been installed and it does not permit
-     *          datagrams to be sent to the given address
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    public abstract <A> void send(ByteBuffer src,
-                                  SocketAddress target,
-                                  A attachment,
-                                  CompletionHandler<Integer,? super A> handler);
-
-    /**
-     * Sends a datagram via this channel.
-     *
-     * <p> This method initiates sending of a datagram from the given buffer to
-     * the given address. The method behaves in exactly the same manner as the
-     * {@link #send(ByteBuffer,SocketAddress,Object,CompletionHandler)
-     * send(ByteBuffer,SocketAddress,Object,CompletionHandler)} method except
-     * that instead of specifying a completion handler, this method returns a
-     * {@code Future} representing the pending result. The {@code Future}'s
-     * {@link Future#get() get} method returns the number of bytes sent.
-     *
-     * @param   src
-     *          The buffer containing the datagram to be sent
-     * @param   target
-     *          The address to which the datagram is to be sent
-     *
-     * @return  a {@code Future} object representing the pending result
-     *
-     * @throws  UnresolvedAddressException
-     *          If the given remote address is not fully resolved
-     * @throws  UnsupportedAddressTypeException
-     *          If the type of the given remote address is not supported
-     * @throws  IllegalArgumentException
-     *          If the channel's socket is connected and is connected to an
-     *          address that is not equal to {@code target}
-     * @throws  SecurityException
-     *          If a security manager has been installed and it does not permit
-     *          datagrams to be sent to the given address
-     */
-    public abstract Future<Integer> send(ByteBuffer src, SocketAddress target);
-
-    /**
-     * Receives a datagram via this channel.
-     *
-     * <p> This method initiates the receiving of a datagram into the given
-     * buffer. The {@code handler} parameter is a completion handler that is
-     * invoked when the receive operation completes (or fails). The result
-     * passed to the completion handler is number of bytes read.
-     *
-     * <p> This method may only be invoked if this channel is connected, and it
-     * only accepts datagrams from the peer that the channel is connected too.
-     * The datagram is transferred into the given byte buffer starting at
-     * its current position and exactly as specified in the {@link
-     * AsynchronousByteChannel} interface. If there are fewer bytes
-     * remaining in the buffer than are required to hold the datagram then the
-     * remainder of the datagram is silently discarded.
-     *
-     * <p> If a timeout is specified and the timeout elapses before the operation
-     * completes then the operation completes with the exception {@link
-     * InterruptedByTimeoutException}. When a timeout elapses then the state of
-     * the {@link ByteBuffer} is not defined. The buffers should be discarded or
-     * at least care must be taken to ensure that the buffer is not accessed
-     * while the channel remains open.
-     *
-     * @param   dst
-     *          The buffer into which the datagram is to be transferred
-     * @param   timeout
-     *          The timeout, or {@code 0L} for no timeout
-     * @param   unit
-     *          The time unit of the {@code timeout} argument
-     * @param   attachment
-     *          The object to attach to the I/O operation; can be {@code null}
-     * @param   handler
-     *          The handler for consuming the result
-     *
-     * @throws  IllegalArgumentException
-     *          If the timeout is negative or buffer is read-only
-     * @throws  NotYetConnectedException
-     *          If this channel is not connected
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    public abstract <A> void read(ByteBuffer dst,
-                                  long timeout,
-                                  TimeUnit unit,
-                                  A attachment,
-                                  CompletionHandler<Integer,? super A> handler);
-
-    /**
-     * @throws  NotYetConnectedException
-     *          If this channel is not connected
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    @Override
-    public final <A> void read(ByteBuffer dst,
-                               A attachment,
-                               CompletionHandler<Integer,? super A> handler)
-    {
-        read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
-    }
-
-    /**
-     * @throws  NotYetConnectedException
-     *          If this channel is not connected
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    @Override
-    public abstract Future<Integer> read(ByteBuffer dst);
-
-    /**
-     * @throws  NotYetConnectedException
-     *          If this channel is not connected
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    @Override
-    public abstract <A> void  write(ByteBuffer src,
-                                    A attachment,
-                                    CompletionHandler<Integer,? super A> handler);
-
-
-    /**
-     * @throws  NotYetConnectedException
-     *          If this channel is not connected
-     * @throws  ShutdownChannelGroupException
-     *          If the channel group has terminated
-     */
-    @Override
-    public abstract Future<Integer> write(ByteBuffer src);
-}
--- a/src/share/classes/java/nio/channels/package-info.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/nio/channels/package-info.java	Thu Nov 11 18:46:02 2010 -0800
@@ -232,8 +232,6 @@
  *     <td>An asynchronous channel to a stream-oriented connecting socket</td></tr>
  * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousServerSocketChannel}&nbsp;&nbsp;</tt></td>
  *     <td>An asynchronous channel to a stream-oriented listening socket</td></tr>
- * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousDatagramChannel}</tt></td>
- *     <td>An asynchronous channel to a datagram-oriented socket</td></tr>
  * <tr><td valign=top><tt>{@link java.nio.channels.CompletionHandler}</tt></td>
  *     <td>A handler for consuming the result of an asynchronous operation</td></tr>
  * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousChannelGroup}</tt></td>
--- a/src/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java	Thu Nov 11 18:46:02 2010 -0800
@@ -26,7 +26,6 @@
 package java.nio.channels.spi;
 
 import java.nio.channels.*;
-import java.net.ProtocolFamily;
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.ServiceLoader;
@@ -239,26 +238,4 @@
      */
     public abstract AsynchronousSocketChannel openAsynchronousSocketChannel
         (AsynchronousChannelGroup group) throws IOException;
-
-    /**
-     * Opens an asynchronous datagram channel.
-     *
-     * @param   family
-     *          The protocol family, or {@code null} for the default protocol
-     *          family
-     * @param   group
-     *          The group to which the channel is bound, or {@code null} to
-     *          bind to the default group
-     *
-     * @return  The new channel
-     *
-     * @throws  IllegalChannelGroupException
-     *          If the provider that created the group differs from this provider
-     * @throws  ShutdownChannelGroupException
-     *          The group is shutdown
-     * @throws  IOException
-     *          If an I/O error occurs
-     */
-    public abstract AsynchronousDatagramChannel openAsynchronousDatagramChannel
-        (ProtocolFamily family, AsynchronousChannelGroup group) throws IOException;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/security/AlgorithmConstraints.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.security;
+
+import java.util.Set;
+
+/**
+ * This interface specifies constraints for cryptographic algorithms,
+ * keys (key sizes), and other algorithm parameters.
+ * <p>
+ * {@code AlgorithmConstraints} objects are immutable.  An implementation
+ * of this interface should not provide methods that can change the state
+ * of an instance once it has been created.
+ * <p>
+ * Note that {@code AlgorithmConstraints} can be used to represent the
+ * restrictions described by the security properties
+ * {@code jdk.certpath.disabledAlgorithms} and
+ * {@code jdk.tls.disabledAlgorithms}, or could be used by a
+ * concrete {@code PKIXCertPathChecker} to check whether a specified
+ * certificate in the certification path contains the required algorithm
+ * constraints.
+ *
+ * @see javax.net.ssl.SSLParameters#getAlgorithmConstraints
+ * @see javax.net.ssl.SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ *
+ * @since 1.7
+ */
+
+public interface AlgorithmConstraints {
+
+    /**
+     * Determines whether an algorithm is granted permission for the
+     * specified cryptographic primitives.
+     *
+     * @param primitives a set of cryptographic primitives
+     * @param algorithm the algorithm name
+     * @param parameters the algorithm parameters, or null if no additional
+     *     parameters
+     *
+     * @return true if the algorithm is permitted and can be used for all
+     *     of the specified cryptographic primitives
+     *
+     * @throws IllegalArgumentException if primitives or algorithm is null
+     *     or empty
+     */
+    public boolean permits(Set<CryptoPrimitive> primitives,
+            String algorithm, AlgorithmParameters parameters);
+
+    /**
+     * Determines whether a key is granted permission for the specified
+     * cryptographic primitives.
+     * <p>
+     * This method is usually used to check key size and key usage.
+     *
+     * @param primitives a set of cryptographic primitives
+     * @param key the key
+     *
+     * @return true if the key can be used for all of the specified
+     *     cryptographic primitives
+     *
+     * @throws IllegalArgumentException if primitives is null or empty,
+     *     or the key is null
+     */
+    public boolean permits(Set<CryptoPrimitive> primitives, Key key);
+
+    /**
+     * Determines whether an algorithm and the corresponding key are granted
+     * permission for the specified cryptographic primitives.
+     *
+     * @param primitives a set of cryptographic primitives
+     * @param algorithm the algorithm name
+     * @param key the key
+     * @param parameters the algorithm parameters, or null if no additional
+     *     parameters
+     *
+     * @return true if the key and the algorithm can be used for all of the
+     *     specified cryptographic primitives
+     *
+     * @throws IllegalArgumentException if primitives or algorithm is null
+     *     or empty, or the key is null
+     */
+    public boolean permits(Set<CryptoPrimitive> primitives,
+                String algorithm, Key key, AlgorithmParameters parameters);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/security/CryptoPrimitive.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.security;
+
+/**
+ * An enumeration of cryptographic primitives.
+ *
+ * @since 1.7
+ */
+public enum CryptoPrimitive {
+    /**
+     * Hash function
+     */
+    MESSAGE_DIGEST,
+
+    /**
+     * Cryptographic random number generator
+     */
+    SECURE_RANDOM,
+
+    /**
+     * Symmetric primitive: block cipher
+     */
+    BLOCK_CIPHER,
+
+    /**
+     * Symmetric primitive: stream cipher
+     */
+    STREAM_CIPHER,
+
+    /**
+     * Symmetric primitive: message authentication code
+     */
+    MAC,
+
+    /**
+     * Symmetric primitive: key wrap
+     */
+    KEY_WRAP,
+
+    /**
+     * Asymmetric primitive: public key encryption
+     */
+    PUBLIC_KEY_ENCRYPTION,
+
+    /**
+     * Asymmetric primitive: signature scheme
+     */
+    SIGNATURE,
+
+    /**
+     * Asymmetric primitive: key encapsulation mechanism
+     */
+    KEY_ENCAPSULATION,
+
+    /**
+     * Asymmetric primitive: key agreement and key distribution
+     */
+    KEY_AGREEMENT
+}
--- a/src/share/classes/java/text/DateFormatSymbols.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/text/DateFormatSymbols.java	Thu Nov 11 18:46:02 2010 -0800
@@ -44,11 +44,12 @@
 import java.lang.ref.SoftReference;
 import java.text.spi.DateFormatSymbolsProvider;
 import java.util.Arrays;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Locale;
 import java.util.ResourceBundle;
 import java.util.TimeZone;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.spi.LocaleServiceProvider;
 import sun.util.LocaleServiceProviderPool;
 import sun.util.TimeZoneNameUtility;
@@ -321,20 +322,64 @@
      * @since 1.6
      */
     public static final DateFormatSymbols getInstance(Locale locale) {
+        DateFormatSymbols dfs = getProviderInstance(locale);
+        if (dfs != null) {
+            return dfs;
+        }
+        return (DateFormatSymbols) getCachedInstance(locale).clone();
+    }
+
+    /**
+     * Returns a DateFormatSymbols provided by a provider or found in
+     * the cache. Note that this method returns a cached instance,
+     * not its clone. Therefore, the instance should never be given to
+     * an application.
+     */
+    static final DateFormatSymbols getInstanceRef(Locale locale) {
+        DateFormatSymbols dfs = getProviderInstance(locale);
+        if (dfs != null) {
+            return dfs;
+        }
+        return getCachedInstance(locale);
+    }
+
+    private static DateFormatSymbols getProviderInstance(Locale locale) {
+        DateFormatSymbols providersInstance = null;
 
         // Check whether a provider can provide an implementation that's closer
         // to the requested locale than what the Java runtime itself can provide.
         LocaleServiceProviderPool pool =
             LocaleServiceProviderPool.getPool(DateFormatSymbolsProvider.class);
         if (pool.hasProviders()) {
-            DateFormatSymbols providersInstance = pool.getLocalizedObject(
-                                DateFormatSymbolsGetter.INSTANCE, locale);
-            if (providersInstance != null) {
-                return providersInstance;
+            providersInstance = pool.getLocalizedObject(
+                                    DateFormatSymbolsGetter.INSTANCE, locale);
+        }
+        return providersInstance;
+    }
+
+    /**
+     * Returns a cached DateFormatSymbols if it's found in the
+     * cache. Otherwise, this method returns a newly cached instance
+     * for the given locale.
+     */
+    private static DateFormatSymbols getCachedInstance(Locale locale) {
+        SoftReference<DateFormatSymbols> ref = cachedInstances.get(locale);
+        DateFormatSymbols dfs = null;
+        if (ref == null || (dfs = ref.get()) == null) {
+            dfs = new DateFormatSymbols(locale);
+            ref = new SoftReference<DateFormatSymbols>(dfs);
+            SoftReference<DateFormatSymbols> x = cachedInstances.putIfAbsent(locale, ref);
+            if (x != null) {
+                DateFormatSymbols y = x.get();
+                if (y != null) {
+                    dfs = y;
+                } else {
+                    // Replace the empty SoftReference with ref.
+                    cachedInstances.put(locale, ref);
+                }
             }
         }
-
-        return new DateFormatSymbols(locale);
+        return dfs;
     }
 
     /**
@@ -597,56 +642,44 @@
     static final int millisPerHour = 60*60*1000;
 
     /**
-     * Cache to hold the FormatData and TimeZoneNames ResourceBundles
-     * of a Locale.
+     * Cache to hold DateFormatSymbols instances per Locale.
      */
-    private static Hashtable cachedLocaleData = new Hashtable(3);
-
-    /**
-     * Look up resource data for the desiredLocale in the cache; update the
-     * cache if necessary.
-     */
-    private static ResourceBundle cacheLookup(Locale desiredLocale) {
-        ResourceBundle rb;
-        SoftReference data
-            = (SoftReference)cachedLocaleData.get(desiredLocale);
-        if (data == null) {
-            rb = LocaleData.getDateFormatData(desiredLocale);
-            data = new SoftReference(rb);
-            cachedLocaleData.put(desiredLocale, data);
-        } else {
-            if ((rb = (ResourceBundle)data.get()) == null) {
-                rb = LocaleData.getDateFormatData(desiredLocale);
-                data = new SoftReference(rb);
-            }
-        }
-        return rb;
-    }
+    private static final ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> cachedInstances
+        = new ConcurrentHashMap<Locale, SoftReference<DateFormatSymbols>>(3);
 
     private void initializeData(Locale desiredLocale) {
-        int i;
-        ResourceBundle resource = cacheLookup(desiredLocale);
+        locale = desiredLocale;
 
-        // FIXME: cache only ResourceBundle. Hence every time, will do
-        // getObject(). This won't be necessary if the Resource itself
-        // is cached.
-        eras = (String[])resource.getObject("Eras");
+        // Copy values of a cached instance if any.
+        SoftReference<DateFormatSymbols> ref = cachedInstances.get(locale);
+        DateFormatSymbols dfs;
+        if (ref != null && (dfs = ref.get()) != null) {
+            copyMembers(dfs, this);
+            return;
+        }
+
+        // Initialize the fields from the ResourceBundle for locale.
+        ResourceBundle resource = LocaleData.getDateFormatData(locale);
+
+        eras = resource.getStringArray("Eras");
         months = resource.getStringArray("MonthNames");
         shortMonths = resource.getStringArray("MonthAbbreviations");
-        String[] lWeekdays = resource.getStringArray("DayNames");
-        weekdays = new String[8];
-        weekdays[0] = "";  // 1-based
-        for (i=0; i<lWeekdays.length; i++)
-            weekdays[i+1] = lWeekdays[i];
-        String[] sWeekdays = resource.getStringArray("DayAbbreviations");
-        shortWeekdays = new String[8];
-        shortWeekdays[0] = "";  // 1-based
-        for (i=0; i<sWeekdays.length; i++)
-            shortWeekdays[i+1] = sWeekdays[i];
         ampms = resource.getStringArray("AmPmMarkers");
         localPatternChars = resource.getString("DateTimePatternChars");
 
-        locale = desiredLocale;
+        // Day of week names are stored in a 1-based array.
+        weekdays = toOneBasedArray(resource.getStringArray("DayNames"));
+        shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations"));
+    }
+
+    private static String[] toOneBasedArray(String[] src) {
+        int len = src.length;
+        String[] dst = new String[len + 1];
+        dst[0] = "";
+        for (int i = 0; i < len; i++) {
+            dst[i + 1] = src[i];
+        }
+        return dst;
     }
 
     /**
--- a/src/share/classes/java/text/DecimalFormat.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/text/DecimalFormat.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,9 +46,10 @@
 import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.Currency;
-import java.util.Hashtable;
 import java.util.Locale;
 import java.util.ResourceBundle;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import sun.util.resources.LocaleData;
@@ -394,14 +395,14 @@
     public DecimalFormat() {
         Locale def = Locale.getDefault(Locale.Category.FORMAT);
         // try to get the pattern from the cache
-        String pattern = (String) cachedLocaleData.get(def);
+        String pattern = cachedLocaleData.get(def);
         if (pattern == null) {  /* cache miss */
             // Get the pattern for the default locale.
             ResourceBundle rb = LocaleData.getNumberFormatData(def);
             String[] all = rb.getStringArray("NumberPatterns");
             pattern = all[0];
             /* update cache */
-            cachedLocaleData.put(def, pattern);
+            cachedLocaleData.putIfAbsent(def, pattern);
         }
 
         // Always applyPattern after the symbols are set
@@ -3272,5 +3273,6 @@
     /**
      * Cache to hold the NumberPattern of a Locale.
      */
-    private static Hashtable cachedLocaleData = new Hashtable(3);
+    private static final ConcurrentMap<Locale, String> cachedLocaleData
+        = new ConcurrentHashMap<Locale, String>(3);
 }
--- a/src/share/classes/java/text/SimpleDateFormat.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/text/SimpleDateFormat.java	Thu Nov 11 18:46:02 2010 -0800
@@ -44,13 +44,14 @@
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
-import java.util.Hashtable;
 import java.util.Locale;
 import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import sun.util.calendar.CalendarUtils;
 import sun.util.calendar.ZoneInfoFile;
 import sun.util.resources.LocaleData;
@@ -503,14 +504,14 @@
     /**
      * Cache to hold the DateTimePatterns of a Locale.
      */
-    private static Hashtable<String,String[]> cachedLocaleData
-        = new Hashtable<String,String[]>(3);
+    private static final ConcurrentMap<String, String[]> cachedLocaleData
+        = new ConcurrentHashMap<String, String[]>(3);
 
     /**
      * Cache NumberFormat instances with Locale key.
      */
-    private static Hashtable<Locale,NumberFormat> cachedNumberFormatData
-        = new Hashtable<Locale,NumberFormat>(3);
+    private static final ConcurrentMap<Locale, NumberFormat> cachedNumberFormatData
+        = new ConcurrentHashMap<Locale, NumberFormat>(3);
 
     /**
      * The Locale used to instantiate this
@@ -579,7 +580,7 @@
 
         initializeCalendar(locale);
         this.pattern = pattern;
-        this.formatData = DateFormatSymbols.getInstance(locale);
+        this.formatData = DateFormatSymbols.getInstanceRef(locale);
         this.locale = locale;
         initialize(locale);
     }
@@ -632,9 +633,9 @@
                 dateTimePatterns = r.getStringArray("DateTimePatterns");
             }
             /* update cache */
-            cachedLocaleData.put(key, dateTimePatterns);
+            cachedLocaleData.putIfAbsent(key, dateTimePatterns);
         }
-        formatData = DateFormatSymbols.getInstance(loc);
+        formatData = DateFormatSymbols.getInstanceRef(loc);
         if ((timeStyle >= 0) && (dateStyle >= 0)) {
             Object[] dateTimeArgs = {dateTimePatterns[timeStyle],
                                      dateTimePatterns[dateStyle + 4]};
@@ -665,7 +666,7 @@
             numberFormat.setGroupingUsed(false);
 
             /* update cache */
-            cachedNumberFormatData.put(loc, numberFormat);
+            cachedNumberFormatData.putIfAbsent(loc, numberFormat);
         }
         numberFormat = (NumberFormat) numberFormat.clone();
 
@@ -897,7 +898,7 @@
      * so we can call it from readObject().
      */
     private void initializeDefaultCentury() {
-        calendar.setTime( new Date() );
+        calendar.setTimeInMillis(System.currentTimeMillis());
         calendar.add( Calendar.YEAR, -80 );
         parseAmbiguousDatesAsAfter(calendar.getTime());
     }
@@ -921,7 +922,7 @@
      * @since 1.2
      */
     public void set2DigitYearStart(Date startDate) {
-        parseAmbiguousDatesAsAfter(startDate);
+        parseAmbiguousDatesAsAfter(new Date(startDate.getTime()));
     }
 
     /**
@@ -934,7 +935,7 @@
      * @since 1.2
      */
     public Date get2DigitYearStart() {
-        return defaultCenturyStart;
+        return (Date) defaultCenturyStart.clone();
     }
 
     /**
--- a/src/share/classes/java/util/ArrayList.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/util/ArrayList.java	Thu Nov 11 18:46:02 2010 -0800
@@ -176,6 +176,11 @@
      * @param minCapacity the desired minimum capacity
      */
     public void ensureCapacity(int minCapacity) {
+        if (minCapacity > 0)
+            ensureCapacityInternal(minCapacity);
+    }
+
+    private void ensureCapacityInternal(int minCapacity) {
         modCount++;
         // overflow-conscious code
         if (minCapacity - elementData.length > 0)
@@ -403,7 +408,7 @@
      * @return <tt>true</tt> (as specified by {@link Collection#add})
      */
     public boolean add(E e) {
-        ensureCapacity(size + 1);  // Increments modCount!!
+        ensureCapacityInternal(size + 1);  // Increments modCount!!
         elementData[size++] = e;
         return true;
     }
@@ -420,7 +425,7 @@
     public void add(int index, E element) {
         rangeCheckForAdd(index);
 
-        ensureCapacity(size + 1);  // Increments modCount!!
+        ensureCapacityInternal(size + 1);  // Increments modCount!!
         System.arraycopy(elementData, index, elementData, index + 1,
                          size - index);
         elementData[index] = element;
@@ -524,7 +529,7 @@
     public boolean addAll(Collection<? extends E> c) {
         Object[] a = c.toArray();
         int numNew = a.length;
-        ensureCapacity(size + numNew);  // Increments modCount
+        ensureCapacityInternal(size + numNew);  // Increments modCount
         System.arraycopy(a, 0, elementData, size, numNew);
         size += numNew;
         return numNew != 0;
@@ -550,7 +555,7 @@
 
         Object[] a = c.toArray();
         int numNew = a.length;
-        ensureCapacity(size + numNew);  // Increments modCount
+        ensureCapacityInternal(size + numNew);  // Increments modCount
 
         int numMoved = size - index;
         if (numMoved > 0)
--- a/src/share/classes/java/util/Calendar.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/util/Calendar.java	Thu Nov 11 18:46:02 2010 -0800
@@ -51,6 +51,8 @@
 import java.security.ProtectionDomain;
 import java.text.DateFormat;
 import java.text.DateFormatSymbols;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import sun.util.BuddhistCalendar;
 import sun.util.calendar.ZoneInfo;
 import sun.util.resources.LocaleData;
@@ -837,7 +839,8 @@
      * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
      * of a Locale.
      */
-    private static Hashtable<Locale, int[]> cachedLocaleData = new Hashtable<Locale, int[]>(3);
+    private static final ConcurrentMap<Locale, int[]> cachedLocaleData
+        = new ConcurrentHashMap<Locale, int[]>(3);
 
     // Special values of stamp[]
     /**
@@ -1022,7 +1025,7 @@
             // returns a BuddhistCalendar instance.
             if ("th".equals(aLocale.getLanguage())
                     && ("TH".equals(aLocale.getCountry()))) {
-                    cal = new BuddhistCalendar(zone, aLocale);
+                cal = new BuddhistCalendar(zone, aLocale);
             } else {
                 cal = new GregorianCalendar(zone, aLocale);
             }
@@ -2588,7 +2591,7 @@
             data = new int[2];
             data[0] = Integer.parseInt(bundle.getString("firstDayOfWeek"));
             data[1] = Integer.parseInt(bundle.getString("minimalDaysInFirstWeek"));
-            cachedLocaleData.put(desiredLocale, data);
+            cachedLocaleData.putIfAbsent(desiredLocale, data);
         }
         firstDayOfWeek = data[0];
         minimalDaysInFirstWeek = data[1];
--- a/src/share/classes/java/util/Locale.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/util/Locale.java	Thu Nov 11 18:46:02 2010 -0800
@@ -758,7 +758,7 @@
     }
 
     private static void initDefault() {
-        String language, region, country, variant;
+        String language, region, script, country, variant;
         language = AccessController.doPrivileged(
             new GetPropertyAction("user.language", "en"));
         // for compatibility, check for old user.region property
@@ -774,43 +774,41 @@
                 country = region;
                 variant = "";
             }
+            script = "";
         } else {
+            script = AccessController.doPrivileged(
+                new GetPropertyAction("user.script", ""));
             country = AccessController.doPrivileged(
                 new GetPropertyAction("user.country", ""));
             variant = AccessController.doPrivileged(
                 new GetPropertyAction("user.variant", ""));
         }
-        defaultLocale = getInstance(language, country, variant);
+        defaultLocale = getInstance(language, script, country, variant, null);
     }
 
     private static void initDefault(Locale.Category category) {
-        String language, region, country, variant;
+        // make sure defaultLocale is initialized
+        if (defaultLocale == null) {
+            initDefault();
+        }
+
+        Locale defaultCategoryLocale = getInstance(
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.languageKey, defaultLocale.getLanguage())),
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.scriptKey, defaultLocale.getScript())),
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.countryKey, defaultLocale.getCountry())),
+            AccessController.doPrivileged(
+                new GetPropertyAction(category.variantKey, defaultLocale.getVariant())),
+            null);
+
         switch (category) {
         case DISPLAY:
-            language = AccessController.doPrivileged(
-                new GetPropertyAction("user.language.display", ""));
-            if ("".equals(language)) {
-                defaultDisplayLocale = getDefault();
-            } else {
-                country = AccessController.doPrivileged(
-                    new GetPropertyAction("user.country.display", ""));
-                variant = AccessController.doPrivileged(
-                    new GetPropertyAction("user.variant.display", ""));
-                defaultDisplayLocale = getInstance(language, country, variant);
-            }
+            defaultDisplayLocale = defaultCategoryLocale;
             break;
         case FORMAT:
-            language = AccessController.doPrivileged(
-                new GetPropertyAction("user.language.format", ""));
-            if ("".equals(language)) {
-                defaultFormatLocale = getDefault();
-            } else {
-                country = AccessController.doPrivileged(
-                    new GetPropertyAction("user.country.format", ""));
-                variant = AccessController.doPrivileged(
-                    new GetPropertyAction("user.variant.format", ""));
-                defaultFormatLocale = getInstance(language, country, variant);
-            }
+            defaultFormatLocale = defaultCategoryLocale;
             break;
         }
     }
@@ -2124,13 +2122,31 @@
          * Category used to represent the default locale for
          * displaying user interfaces.
          */
-        DISPLAY,
+        DISPLAY("user.language.display",
+                "user.script.display",
+                "user.country.display",
+                "user.variant.display"),
 
         /**
          * Category used to represent the default locale for
          * formatting dates, numbers, and/or currencies.
          */
-        FORMAT,
+        FORMAT("user.language.format",
+               "user.script.format",
+               "user.country.format",
+               "user.variant.format");
+
+        Category(String languageKey, String scriptKey, String countryKey, String variantKey) {
+            this.languageKey = languageKey;
+            this.scriptKey = scriptKey;
+            this.countryKey = countryKey;
+            this.variantKey = variantKey;
+        }
+
+        final String languageKey;
+        final String scriptKey;
+        final String countryKey;
+        final String variantKey;
     }
 
     /**
--- a/src/share/classes/java/util/TimeZone.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/util/TimeZone.java	Thu Nov 11 18:46:02 2010 -0800
@@ -160,11 +160,6 @@
     private static final int ONE_HOUR   = 60*ONE_MINUTE;
     private static final int ONE_DAY    = 24*ONE_HOUR;
 
-    /**
-     * Cache to hold the SimpleDateFormat objects for a Locale.
-     */
-    private static Hashtable cachedLocaleData = new Hashtable(3);
-
     // Proclaim serialization compatibility with JDK 1.1
     static final long serialVersionUID = 3581463369166924961L;
 
--- a/src/share/classes/java/util/Vector.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/util/Vector.java	Thu Nov 11 18:46:02 2010 -0800
@@ -222,8 +222,10 @@
      * @param minCapacity the desired minimum capacity
      */
     public synchronized void ensureCapacity(int minCapacity) {
-        modCount++;
-        ensureCapacityHelper(minCapacity);
+        if (minCapacity > 0) {
+            modCount++;
+            ensureCapacityHelper(minCapacity);
+        }
     }
 
     /**
--- a/src/share/classes/java/util/logging/LogRecord.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/java/util/logging/LogRecord.java	Thu Nov 11 18:46:02 2010 -0800
@@ -529,8 +529,6 @@
         Throwable throwable = new Throwable();
         int depth = access.getStackTraceDepth(throwable);
 
-        String logClassName = "java.util.logging.Logger";
-        String plogClassName = "sun.util.logging.PlatformLogger";
         boolean lookingForLogger = true;
         for (int ix = 0; ix < depth; ix++) {
             // Calling getStackTraceElement directly prevents the VM
@@ -538,13 +536,14 @@
             StackTraceElement frame =
                 access.getStackTraceElement(throwable, ix);
             String cname = frame.getClassName();
+            boolean isLoggerImpl = isLoggerImplFrame(cname);
             if (lookingForLogger) {
                 // Skip all frames until we have found the first logger frame.
-                if (cname.equals(logClassName) || cname.startsWith(plogClassName)) {
+                if (isLoggerImpl) {
                     lookingForLogger = false;
                 }
             } else {
-                if (!cname.equals(logClassName) && !cname.startsWith(plogClassName)) {
+                if (!isLoggerImpl) {
                     // skip reflection call
                     if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
                        // We've found the relevant frame.
@@ -558,4 +557,11 @@
         // We haven't found a suitable frame, so just punt.  This is
         // OK as we are only committed to making a "best effort" here.
     }
+
+    private boolean isLoggerImplFrame(String cname) {
+        // the log record could be created for a platform logger
+        return (cname.equals("java.util.logging.Logger") ||
+                cname.startsWith("java.util.logging.LoggingProxyImpl") ||
+                cname.startsWith("sun.util.logging."));
+    }
 }
--- a/src/share/classes/javax/management/ObjectName.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/management/ObjectName.java	Thu Nov 11 18:46:02 2010 -0800
@@ -211,8 +211,8 @@
  * reverse DNS name of the organization that specifies the MBeans,
  * followed by a period and a string whose interpretation is
  * determined by that organization.  For example, MBeans specified by
- * Sun Microsystems Inc., DNS name <code>sun.com</code>, would have
- * domains such as <code>com.sun.MyDomain</code>.  This is essentially
+ * <code>example.com</code>  would have
+ * domains such as <code>com.example.MyDomain</code>.  This is essentially
  * the same convention as for Java-language package names.</p>
  *
  * <p>The <b>serialVersionUID</b> of this class is <code>1081892073854801359L</code>.
--- a/src/share/classes/javax/management/build.xml	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/management/build.xml	Thu Nov 11 18:46:02 2010 -0800
@@ -35,18 +35,18 @@
      . Please also read the important comment on basedir definition below.
  -->
 
-<project name="JMX API Version 1.4 - Java SE 6 implementation" 
-	 default="jar" 
-	 basedir="../../../../.." 
+<project name="JMX API Version 1.4 - Java SE 6 implementation"
+	 default="jar"
+	 basedir="../../../../.."
 	 >
 
-    <!-- IMPORTANT: BASEDIR DEFINITION  
-         This file is assumed to be in: 
-         <src_bundle_dir>/j2se/src/share/classes/javax/management 
-         Thus the basedir for this project is defined above as: 
-         basedir="../../../../.."  
+    <!-- IMPORTANT: BASEDIR DEFINITION
+         This file is assumed to be in:
+         <src_bundle_dir>/j2se/src/share/classes/javax/management
+         Thus the basedir for this project is defined above as:
+         basedir="../../../../.."
          in order to be the parent dir of src subdir.
-	 Result of the build will be placed in ${basedir}/build_jmx 
+	 Result of the build will be placed in ${basedir}/build_jmx
 	 as defined by ${dir.build} property below.
      -->
 
@@ -163,14 +163,14 @@
         <echo message="   BUILD_DATE                  = ${BUILD_DATE}" />
 
     </target>
-    
+
 
 
     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
     <!-- Call classes subtargets and rmic stubs generation -->
 
-    <target name="classes" depends="init,classes-javac,classes-rmic" 
-	    description="Call classes subtargets and rmic stubs generation" 
+    <target name="classes" depends="init,classes-javac,classes-rmic"
+	    description="Call classes subtargets and rmic stubs generation"
     />
 
 
@@ -183,13 +183,13 @@
         <mkdir dir="${dir.build.classes}" />
 
 	<javac 	srcdir="${dir.src}"
-		destdir="${dir.build.classes}" 
+		destdir="${dir.build.classes}"
 		source="${flag.javac.source}"
 		debug="${flag.debug}"
 		debuglevel="${flag.debug.level}"
 		optimize="${flag.optimize}"
 		includeAntRuntime="no"
-		includeJavaRuntime="no"	
+		includeJavaRuntime="no"
 	        >
 	    <include name="javax/management/**"/>
 	    <include name="com/sun/jmx/**"/>
@@ -253,7 +253,7 @@
 
        <mkdir dir="${dir.build.lib}" />
 
-       <jar jarfile="${dir.build.lib}/jmx.jar" 
+       <jar jarfile="${dir.build.lib}/jmx.jar"
 	    update="true"
 	    >
 
@@ -269,10 +269,10 @@
 		    <attribute name="Sealed"                 value="true" />
 		    <attribute name="Specification-Title"    value="JMX(TM) API" />
 		    <attribute name="Specification-Version"  value="1.4" />
-		    <attribute name="Specification-Vendor"   value="Sun Microsystems, Inc." />
+		    <attribute name="Specification-Vendor"   value="Oracle Corporation" />
 		    <attribute name="Implementation-Title"   value="JMX(TM) API, Java SE 6 implementation" />
-		    <attribute name="Implementation-Version" value="${BUILD_DATE} rebuild of Mustang JMX sources" /> 
-		    <attribute name="Implementation-Vendor"  value="Source bundle from Sun Microsystems, Inc. - Customer rebuilt" />
+		    <attribute name="Implementation-Version" value="${BUILD_DATE} rebuild of Java SE JMX sources" />
+		    <attribute name="Implementation-Vendor"  value="Source bundle from Oracle Corporation - Customer rebuilt" />
 		</section>
 	    </manifest>
        </jar>
@@ -295,16 +295,16 @@
     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
     <!-- Delete build directory and all its contents -->
 
-    <target name="clean-all" 
+    <target name="clean-all"
             description="Delete build directory and all its contents" >
         <delete dir="${dir.build}" />
-    </target>               
-        
-  
+    </target>
+
+
     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
     <!-- Clean all and build everything -->
 
-    <target name="all" depends="clean-all,jar" 
+    <target name="all" depends="clean-all,jar"
 	    description="Clean all and build everything" />
 
 
--- a/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java	Thu Nov 11 18:46:02 2010 -0800
@@ -92,8 +92,6 @@
  * @since 1.5
  */
 
-// Sun Microsystems, Sept. 2002: Revisited for JMX 1.2 (DF)
-//
 @SuppressWarnings("serial")  // serialVersionUID is not constant
 public class ModelMBeanNotificationInfo
     extends MBeanNotificationInfo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/net/ssl/ExtendedSSLSession.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.net.ssl;
+
+/**
+ * Extends the <code>SSLSession</code> interface to support additional
+ * session attributes.
+ *
+ * @since 1.7
+ */
+public abstract class ExtendedSSLSession implements SSLSession {
+    /**
+     * Obtains an array of supported signature algorithms that the local side
+     * is willing to use.
+     * <p>
+     * Note: this method is used to indicate to the peer which signature
+     * algorithms may be used for digital signatures in TLS 1.2. It is
+     * not meaningful for TLS versions prior to 1.2.
+     * <p>
+     * The signature algorithm name must be a standard Java Security
+     * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
+     * See Appendix A in the <a href=
+     * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * Java Cryptography Architecture API Specification &amp; Reference </a>
+     * for information about standard algorithm names.
+     * <p>
+     * Note: the local supported signature algorithms should conform to
+     * the algorithm constraints specified by
+     * {@link SSLParameters#getAlgorithmConstraints getAlgorithmConstraints()}
+     * method in <code>SSLParameters</code>.
+     *
+     * @return An array of supported signature algorithms, in descending
+     *     order of preference.  The return value is an empty array if
+     *     no signature algorithm is supported.
+     *
+     * @see SSLParameters#getAlgorithmConstraints
+     */
+    public abstract String[] getLocalSupportedSignatureAlgorithms();
+
+    /**
+     * Obtains an array of supported signature algorithms that the peer is
+     * able to use.
+     * <p>
+     * Note: this method is used to indicate to the local side which signature
+     * algorithms may be used for digital signatures in TLS 1.2. It is
+     * not meaningful for TLS versions prior to 1.2.
+     * <p>
+     * The signature algorithm name must be a standard Java Security
+     * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
+     * See Appendix A in the <a href=
+     * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     * Java Cryptography Architecture API Specification &amp; Reference </a>
+     * for information about standard algorithm names.
+     *
+     * @return An array of supported signature algorithms, in descending
+     *     order of preference.  The return value is an empty array if
+     *     the peer has not sent the supported signature algorithms.
+     *
+     * @see X509KeyManager
+     * @see X509ExtendedKeyManager
+     */
+    public abstract String[] getPeerSupportedSignatureAlgorithms();
+}
--- a/src/share/classes/javax/net/ssl/HttpsURLConnection.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/net/ssl/HttpsURLConnection.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -188,19 +188,8 @@
      * <p>
      * The default implementation will deny such connections.
      */
-    private static HostnameVerifier defaultHostnameVerifier;
-
-    /**
-     * Initialize the default <code>HostnameVerifier</code>.
-     */
-    static {
-        try {
-            defaultHostnameVerifier =
-                new sun.net.www.protocol.https.DefaultHostnameVerifier();
-        } catch (NoClassDefFoundError e) {
-            defaultHostnameVerifier = new DefaultHostnameVerifier();
-        }
-    }
+    private static HostnameVerifier defaultHostnameVerifier =
+                                        new DefaultHostnameVerifier();
 
     /*
      * The initial default <code>HostnameVerifier</code>.  Should be
--- a/src/share/classes/javax/net/ssl/SSLEngine.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/net/ssl/SSLEngine.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -968,6 +968,47 @@
 
 
     /**
+     * Returns the {@code SSLSession} being constructed during a SSL/TLS
+     * handshake.
+     * <p>
+     * TLS protocols may negotiate parameters that are needed when using
+     * an instance of this class, but before the {@code SSLSession} has
+     * been completely initialized and made available via {@code getSession}.
+     * For example, the list of valid signature algorithms may restrict
+     * the type of certificates that can used during TrustManager
+     * decisions, or the maximum TLS fragment packet sizes can be
+     * resized to better support the network environment.
+     * <p>
+     * This method provides early access to the {@code SSLSession} being
+     * constructed.  Depending on how far the handshake has progressed,
+     * some data may not yet be available for use.  For example, if a
+     * remote server will be sending a Certificate chain, but that chain
+     * has yet not been processed, the {@code getPeerCertificates}
+     * method of {@code SSLSession} will throw a
+     * SSLPeerUnverifiedException.  Once that chain has been processed,
+     * {@code getPeerCertificates} will return the proper value.
+     *
+     * @see SSLSocket
+     * @see SSLSession
+     * @see ExtendedSSLSession
+     * @see X509ExtendedKeyManager
+     * @see X509ExtendedTrustManager
+     *
+     * @return null if this instance is not currently handshaking, or
+     *         if the current handshake has not progressed far enough to
+     *         create a basic SSLSession.  Otherwise, this method returns the
+     *         {@code SSLSession} currently being negotiated.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     *
+     * @since 1.7
+     */
+    public SSLSession getHandshakeSession() {
+        throw new UnsupportedOperationException();
+    }
+
+
+    /**
      * Initiates handshaking (initial or renegotiation) on this SSLEngine.
      * <P>
      * This method is not needed for the initial handshake, as the
--- a/src/share/classes/javax/net/ssl/SSLParameters.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/net/ssl/SSLParameters.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,24 +25,29 @@
 
 package javax.net.ssl;
 
+import java.security.AlgorithmConstraints;
+
 /**
  * Encapsulates parameters for an SSL/TLS connection. The parameters
  * are the list of ciphersuites to be accepted in an SSL/TLS handshake,
- * the list of protocols to be allowed, and whether SSL/TLS servers should
- * request or require client authentication.
- *
- * <p>SSLParameters can be created via the constructors in this class.
+ * the list of protocols to be allowed, the endpoint identification
+ * algorithm during SSL/TLS handshaking, the algorithm constraints and
+ * whether SSL/TLS servers should request or require client authentication.
+ * <p>
+ * SSLParameters can be created via the constructors in this class.
  * Objects can also be obtained using the <code>getSSLParameters()</code>
  * methods in
  * {@link SSLSocket#getSSLParameters SSLSocket} and
+ * {@link SSLServerSocket#getSSLParameters SSLServerSocket} and
  * {@link SSLEngine#getSSLParameters SSLEngine} or the
  * {@link SSLContext#getDefaultSSLParameters getDefaultSSLParameters()} and
  * {@link SSLContext#getSupportedSSLParameters getSupportedSSLParameters()}
  * methods in <code>SSLContext</code>.
- *
- * <P>SSLParameters can be applied to a connection via the methods
+ * <p>
+ * SSLParameters can be applied to a connection via the methods
  * {@link SSLSocket#setSSLParameters SSLSocket.setSSLParameters()} and
- * {@link SSLEngine#setSSLParameters SSLEngine.getSSLParameters()}.
+ * {@link SSLServerSocket#setSSLParameters SSLServerSocket.setSSLParameters()}
+ * and {@link SSLEngine#setSSLParameters SSLEngine.getSSLParameters()}.
  *
  * @see SSLSocket
  * @see SSLEngine
@@ -56,11 +61,13 @@
     private String[] protocols;
     private boolean wantClientAuth;
     private boolean needClientAuth;
+    private String identificationAlgorithm;
+    private AlgorithmConstraints algorithmConstraints;
 
     /**
      * Constructs SSLParameters.
-     *
-     * <p>The cipherSuites and protocols values are set to <code>null</code>,
+     * <p>
+     * The cipherSuites and protocols values are set to <code>null</code>,
      * wantClientAuth and needClientAuth are set to <code>false</code>.
      */
     public SSLParameters() {
@@ -69,6 +76,7 @@
 
     /**
      * Constructs SSLParameters from the specified array of ciphersuites.
+     * <p>
      * Calling this constructor is equivalent to calling the no-args
      * constructor followed by
      * <code>setCipherSuites(cipherSuites);</code>.
@@ -82,6 +90,7 @@
     /**
      * Constructs SSLParameters from the specified array of ciphersuites
      * and protocols.
+     * <p>
      * Calling this constructor is equivalent to calling the no-args
      * constructor followed by
      * <code>setCipherSuites(cipherSuites); setProtocols(protocols);</code>.
@@ -178,4 +187,71 @@
         this.needClientAuth = needClientAuth;
     }
 
+    /**
+     * Returns the cryptographic algorithm constraints.
+     *
+     * @return the cryptographic algorithm constraints, or null if the
+     *     constraints have not been set
+     *
+     * @see #setAlgorithmConstraints(AlgorithmConstraints)
+     *
+     * @since 1.7
+     */
+    public AlgorithmConstraints getAlgorithmConstraints() {
+        return algorithmConstraints;
+    }
+
+    /**
+     * Sets the cryptographic algorithm constraints, which will be used
+     * in addition to any configured by the runtime environment.
+     * <p>
+     * If the <code>constraints</code> parameter is non-null, every
+     * cryptographic algorithm, key and algorithm parameters used in the
+     * SSL/TLS handshake must be permitted by the constraints.
+     *
+     * @param constraints the algorithm constraints (or null)
+     *
+     * @since 1.7
+     */
+    public void setAlgorithmConstraints(AlgorithmConstraints constraints) {
+        // the constraints object is immutable
+        this.algorithmConstraints = constraints;
+    }
+
+    /**
+     * Gets the endpoint identification algorithm.
+     *
+     * @return the endpoint identification algorithm, or null if none
+     * has been set.
+     *
+     * @see X509ExtendedTrustManager
+     * @see #setEndpointIdentificationAlgorithm(String)
+     *
+     * @since 1.7
+     */
+    public String getEndpointIdentificationAlgorithm() {
+        return identificationAlgorithm;
+    }
+
+    /**
+     * Sets the endpoint identification algorithm.
+     * <p>
+     * If the <code>algorithm</code> parameter is non-null or non-empty, the
+     * endpoint identification/verification procedures must be handled during
+     * SSL/TLS handshaking.  This is to prevent man-in-the-middle attacks.
+     *
+     * @param algorithm The standard string name of the endpoint
+     *     identification algorithm (or null).  See Appendix A in the <a href=
+     *     "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+     *     Java Cryptography Architecture API Specification &amp; Reference </a>
+     *     for information about standard algorithm names.
+     *
+     * @see X509ExtendedTrustManager
+     *
+     * @since 1.7
+     */
+    public void setEndpointIdentificationAlgorithm(String algorithm) {
+        this.identificationAlgorithm = algorithm;
+    }
+
 }
--- a/src/share/classes/javax/net/ssl/SSLServerSocket.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/net/ssl/SSLServerSocket.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,8 +56,8 @@
  * @since 1.4
  * @author David Brownell
  */
-public abstract class SSLServerSocket extends ServerSocket
-{
+public abstract class SSLServerSocket extends ServerSocket {
+
     /**
      * Used only by subclasses.
      * <P>
@@ -449,8 +449,79 @@
      *
      * @return true indicates that sessions may be created; this
      *          is the default.  false indicates that an existing
-     *          session must be resumed.
+     *          session must be resumed
      * @see #setEnableSessionCreation(boolean)
      */
     public abstract boolean getEnableSessionCreation();
+
+    /**
+     * Returns the SSLParameters in effect for newly accepted connections.
+     * The ciphersuites and protocols of the returned SSLParameters
+     * are always non-null.
+     *
+     * @return the SSLParameters in effect for newly accepted connections
+     *
+     * @see #setSSLParameters(SSLParameters)
+     *
+     * @since 1.7
+     */
+    public SSLParameters getSSLParameters() {
+        SSLParameters parameters = new SSLParameters();
+
+        parameters.setCipherSuites(getEnabledCipherSuites());
+        parameters.setProtocols(getEnabledProtocols());
+        if (getNeedClientAuth()) {
+            parameters.setNeedClientAuth(true);
+        } else if (getWantClientAuth()) {
+            parameters.setWantClientAuth(true);
+        }
+
+        return parameters;
+    }
+
+    /**
+     * Applies SSLParameters to newly accepted connections.
+     *
+     * <p>This means:
+     * <ul>
+     * <li>if <code>params.getCipherSuites()</code> is non-null,
+     *   <code>setEnabledCipherSuites()</code> is called with that value
+     * <li>if <code>params.getProtocols()</code> is non-null,
+     *   <code>setEnabledProtocols()</code> is called with that value
+     * <li>if <code>params.getNeedClientAuth()</code> or
+     *   <code>params.getWantClientAuth()</code> return <code>true</code>,
+     *   <code>setNeedClientAuth(true)</code> and
+     *   <code>setWantClientAuth(true)</code> are called, respectively;
+     *   otherwise <code>setWantClientAuth(false)</code> is called.
+     * </ul>
+     *
+     * @param params the parameters
+     * @throws IllegalArgumentException if the setEnabledCipherSuites() or
+     *    the setEnabledProtocols() call fails
+     *
+     * @see #getSSLParameters()
+     *
+     * @since 1.7
+     */
+    public void setSSLParameters(SSLParameters params) {
+        String[] s;
+        s = params.getCipherSuites();
+        if (s != null) {
+            setEnabledCipherSuites(s);
+        }
+
+        s = params.getProtocols();
+        if (s != null) {
+            setEnabledProtocols(s);
+        }
+
+        if (params.getNeedClientAuth()) {
+            setNeedClientAuth(true);
+        } else if (params.getWantClientAuth()) {
+            setWantClientAuth(true);
+        } else {
+            setWantClientAuth(false);
+        }
+    }
+
 }
--- a/src/share/classes/javax/net/ssl/SSLSocket.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/net/ssl/SSLSocket.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -371,6 +371,51 @@
 
 
     /**
+     * Returns the {@code SSLSession} being constructed during a SSL/TLS
+     * handshake.
+     * <p>
+     * TLS protocols may negotiate parameters that are needed when using
+     * an instance of this class, but before the {@code SSLSession} has
+     * been completely initialized and made available via {@code getSession}.
+     * For example, the list of valid signature algorithms may restrict
+     * the type of certificates that can used during TrustManager
+     * decisions, or the maximum TLS fragment packet sizes can be
+     * resized to better support the network environment.
+     * <p>
+     * This method provides early access to the {@code SSLSession} being
+     * constructed.  Depending on how far the handshake has progressed,
+     * some data may not yet be available for use.  For example, if a
+     * remote server will be sending a Certificate chain, but that chain
+     * has yet not been processed, the {@code getPeerCertificates}
+     * method of {@code SSLSession} will throw a
+     * SSLPeerUnverifiedException.  Once that chain has been processed,
+     * {@code getPeerCertificates} will return the proper value.
+     * <p>
+     * Unlike {@link #getSession()}, this method does not initiate the
+     * initial handshake and does not block until handshaking is
+     * complete.
+     *
+     * @see SSLEngine
+     * @see SSLSession
+     * @see ExtendedSSLSession
+     * @see X509ExtendedKeyManager
+     * @see X509ExtendedTrustManager
+     *
+     * @return null if this instance is not currently handshaking, or
+     *         if the current handshake has not progressed far enough to
+     *         create a basic SSLSession.  Otherwise, this method returns the
+     *         {@code SSLSession} currently being negotiated.
+     * @throws UnsupportedOperationException if the underlying provider
+     *         does not implement the operation.
+     *
+     * @since 1.7
+     */
+    public SSLSession getHandshakeSession() {
+        throw new UnsupportedOperationException();
+    }
+
+
+    /**
      * Registers an event listener to receive notifications that an
      * SSL handshake has completed on this connection.
      *
--- a/src/share/classes/javax/net/ssl/SSLSocketFactory.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/net/ssl/SSLSocketFactory.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 import javax.net.SocketFactory;
 import java.io.IOException;
 import java.security.*;
+import java.util.Locale;
 
 import sun.security.action.GetPropertyAction;
 
@@ -50,7 +51,8 @@
 
     static {
         String s = java.security.AccessController.doPrivileged(
-            new GetPropertyAction("javax.net.debug", "")).toLowerCase();
+            new GetPropertyAction("javax.net.debug", "")).toLowerCase(
+                                                            Locale.ENGLISH);
         DEBUG = s.contains("all") || s.contains("ssl");
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/net/ssl/X509ExtendedTrustManager.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.net.ssl;
+
+import java.net.Socket;
+import javax.net.ssl.X509TrustManager;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+
+/**
+ * Extensions to the <code>X509TrustManager</code> interface to support
+ * SSL/TLS connection sensitive trust management.
+ * <p>
+ * To prevent man-in-the-middle attacks, hostname checks can be done
+ * to verify that the hostname in an end-entity certificate matches the
+ * targeted hostname.  TLS does not require such checks, but some protocols
+ * over TLS (such as HTTPS) do.  In earlier versions of the JDK, the
+ * certificate chain checks were done at the SSL/TLS layer, and the hostname
+ * verification checks were done at the layer over TLS.  This class allows
+ * for the checking to be done during a single call to this class.
+ * <p>
+ * RFC 2830 defines the server identification specification for the "LDAPS"
+ * algorithm. RFC 2818 defines both the server identification and the
+ * client identification specification for the "HTTPS" algorithm.
+ *
+ * @see X509TrustManager
+ * @see HostnameVerifier
+ *
+ * @since 1.7
+ */
+public abstract class X509ExtendedTrustManager implements X509TrustManager {
+    /**
+     * Given the partial or complete certificate chain provided by the
+     * peer, build and validate the certificate path based on the
+     * authentication type and ssl parameters.
+     * <p>
+     * The authentication type is determined by the actual certificate
+     * used. For instance, if RSAPublicKey is used, the authType
+     * should be "RSA". Checking is case-sensitive.
+     * <p>
+     * If the <code>socket</code> parameter is an instance of
+     * {@link javax.net.SSLSocket}, and the endpoint identification
+     * algorithm of the <code>SSLParameters</code> is non-empty, to prevent
+     * man-in-the-middle attacks, the address that the <code>socket</code>
+     * connected to should be checked against the peer's identity presented
+     * in the end-entity X509 certificate, as specified in the endpoint
+     * identification algorithm.
+     * <p>
+     * If the <code>socket</code> parameter is an instance of
+     * {@link javax.net.SSLSocket}, and the algorithm constraints of the
+     * <code>SSLParameters</code> is non-null, for every certificate in the
+     * certification path, fields such as subject public key, the signature
+     * algorithm, key usage, extended key usage, etc. need to conform to the
+     * algorithm constraints in place on this socket.
+     *
+     * @param chain the peer certificate chain
+     * @param authType the key exchange algorithm used
+     * @param socket the socket used for this connection. This parameter
+     *        can be null, which indicates that implementations need not check
+     *        the ssl parameters
+     * @throws IllegalArgumentException if null or zero-length array is passed
+     *        in for the <code>chain</code> parameter or if null or zero-length
+     *        string is passed in for the <code>authType</code> parameter
+     * @throws CertificateException if the certificate chain is not trusted
+     *        by this TrustManager
+     *
+     * @see SSLParameters#getEndpointIdentificationProtocol
+     * @see SSLParameters#setEndpointIdentificationProtocol(String)
+     * @see SSLParameters#getAlgorithmConstraints
+     * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+     */
+    public abstract void checkClientTrusted(X509Certificate[] chain,
+            String authType, Socket socket) throws CertificateException;
+
+    /**
+     * Given the partial or complete certificate chain provided by the
+     * peer, build and validate the certificate path based on the
+     * authentication type and ssl parameters.
+     * <p>
+     * The authentication type is the key exchange algorithm portion
+     * of the cipher suites represented as a String, such as "RSA",
+     * "DHE_DSS". Note: for some exportable cipher suites, the key
+     * exchange algorithm is determined at run time during the
+     * handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
+     * the authType should be RSA_EXPORT when an ephemeral RSA key is
+     * used for the key exchange, and RSA when the key from the server
+     * certificate is used. Checking is case-sensitive.
+     * <p>
+     * If the <code>socket</code> parameter is an instance of
+     * {@link javax.net.SSLSocket}, and the endpoint identification
+     * algorithm of the <code>SSLParameters</code> is non-empty, to prevent
+     * man-in-the-middle attacks, the address that the <code>socket</code>
+     * connected to should be checked against the peer's identity presented
+     * in the end-entity X509 certificate, as specified in the endpoint
+     * identification algorithm.
+     * <p>
+     * If the <code>socket</code> parameter is an instance of
+     * {@link javax.net.SSLSocket}, and the algorithm constraints of the
+     *  <code>SSLParameters</code> is non-null, for every certificate in the
+     * certification path, fields such as subject public key, the signature
+     * algorithm, key usage, extended key usage, etc. need to conform to the
+     * algorithm constraints in place on this socket.
+     *
+     * @param chain the peer certificate chain
+     * @param authType the key exchange algorithm used
+     * @param socket the socket used for this connection. This parameter
+     *        can be null, which indicates that implementations need not check
+     *        the ssl parameters
+     * @throws IllegalArgumentException if null or zero-length array is passed
+     *        in for the <code>chain</code> parameter or if null or zero-length
+     *        string is passed in for the <code>authType</code> parameter
+     * @throws CertificateException if the certificate chain is not trusted
+     *        by this TrustManager
+     *
+     * @see SSLParameters#getEndpointIdentificationProtocol
+     * @see SSLParameters#setEndpointIdentificationProtocol(String)
+     * @see SSLParameters#getAlgorithmConstraints
+     * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+     */
+    public abstract void checkServerTrusted(X509Certificate[] chain,
+        String authType, Socket socket) throws CertificateException;
+
+    /**
+     * Given the partial or complete certificate chain provided by the
+     * peer, build and validate the certificate path based on the
+     * authentication type and ssl parameters.
+     * <p>
+     * The authentication type is determined by the actual certificate
+     * used. For instance, if RSAPublicKey is used, the authType
+     * should be "RSA". Checking is case-sensitive.
+     * <p>
+     * If the <code>engine</code> parameter is available, and the endpoint
+     * identification algorithm of the <code>SSLParameters</code> is
+     * non-empty, to prevent man-in-the-middle attacks, the address that
+     * the <code>engine</code> connected to should be checked against
+     * the peer's identity presented in the end-entity X509 certificate,
+     * as specified in the endpoint identification algorithm.
+     * <p>
+     * If the <code>engine</code> parameter is available, and the algorithm
+     * constraints of the <code>SSLParameters</code> is non-null, for every
+     * certificate in the certification path, fields such as subject public
+     * key, the signature algorithm, key usage, extended key usage, etc.
+     * need to conform to the algorithm constraints in place on this engine.
+     *
+     * @param chain the peer certificate chain
+     * @param authType the key exchange algorithm used
+     * @param engine the engine used for this connection. This parameter
+     *        can be null, which indicates that implementations need not check
+     *        the ssl parameters
+     * @throws IllegalArgumentException if null or zero-length array is passed
+     *        in for the <code>chain</code> parameter or if null or zero-length
+     *        string is passed in for the <code>authType</code> parameter
+     * @throws CertificateException if the certificate chain is not trusted
+     *        by this TrustManager
+     *
+     * @see SSLParameters#getEndpointIdentificationProtocol
+     * @see SSLParameters#setEndpointIdentificationProtocol(String)
+     * @see SSLParameters#getAlgorithmConstraints
+     * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+     */
+    public abstract void checkClientTrusted(X509Certificate[] chain,
+        String authType, SSLEngine engine) throws CertificateException;
+
+    /**
+     * Given the partial or complete certificate chain provided by the
+     * peer, build and validate the certificate path based on the
+     * authentication type and ssl parameters.
+     * <p>
+     * The authentication type is the key exchange algorithm portion
+     * of the cipher suites represented as a String, such as "RSA",
+     * "DHE_DSS". Note: for some exportable cipher suites, the key
+     * exchange algorithm is determined at run time during the
+     * handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
+     * the authType should be RSA_EXPORT when an ephemeral RSA key is
+     * used for the key exchange, and RSA when the key from the server
+     * certificate is used. Checking is case-sensitive.
+     * <p>
+     * If the <code>engine</code> parameter is available, and the endpoint
+     * identification algorithm of the <code>SSLParameters</code> is
+     * non-empty, to prevent man-in-the-middle attacks, the address that
+     * the <code>engine</code> connected to should be checked against
+     * the peer's identity presented in the end-entity X509 certificate,
+     * as specified in the endpoint identification algorithm.
+     * <p>
+     * If the <code>engine</code> parameter is available, and the algorithm
+     * constraints of the <code>SSLParameters</code> is non-null, for every
+     * certificate in the certification path, fields such as subject public
+     * key, the signature algorithm, key usage, extended key usage, etc.
+     * need to conform to the algorithm constraints in place on this engine.
+     *
+     * @param chain the peer certificate chain
+     * @param authType the key exchange algorithm used
+     * @param engine the engine used for this connection. This parameter
+     *        can be null, which indicates that implementations need not check
+     *        the ssl parameters
+     * @throws IllegalArgumentException if null or zero-length array is passed
+     *        in for the <code>chain</code> parameter or if null or zero-length
+     *        string is passed in for the <code>authType</code> parameter
+     * @throws CertificateException if the certificate chain is not trusted
+     *        by this TrustManager
+     *
+     * @see SSLParameters#getEndpointIdentificationProtocol
+     * @see SSLParameters#setEndpointIdentificationProtocol(String)
+     * @see SSLParameters#getAlgorithmConstraints
+     * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+     */
+    public abstract void checkServerTrusted(X509Certificate[] chain,
+        String authType, SSLEngine engine) throws CertificateException;
+
+}
--- a/src/share/classes/javax/swing/BorderFactory.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/BorderFactory.java	Thu Nov 11 18:46:02 2010 -0800
@@ -24,8 +24,10 @@
  */
 package javax.swing;
 
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Font;
+import java.awt.Paint;
 import javax.swing.border.*;
 
 /**
@@ -636,4 +638,125 @@
                                                 Icon tileIcon) {
         return new MatteBorder(top, left, bottom, right, tileIcon);
     }
+
+//// StrokeBorder //////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Creates a border of the specified {@code stroke}.
+     * The component's foreground color will be used to render the border.
+     *
+     * @param stroke  the {@link BasicStroke} object used to stroke a shape
+     * @return the {@code Border} object
+     *
+     * @throws NullPointerException if the specified {@code stroke} is {@code null}
+     *
+     * @since 1.7
+     */
+    public static Border createStrokeBorder(BasicStroke stroke) {
+        return new StrokeBorder(stroke);
+    }
+
+    /**
+     * Creates a border of the specified {@code stroke} and {@code paint}.
+     * If the specified {@code paint} is {@code null},
+     * the component's foreground color will be used to render the border.
+     *
+     * @param stroke  the {@link BasicStroke} object used to stroke a shape
+     * @param paint   the {@link Paint} object used to generate a color
+     * @return the {@code Border} object
+     *
+     * @throws NullPointerException if the specified {@code stroke} is {@code null}
+     *
+     * @since 1.7
+     */
+    public static Border createStrokeBorder(BasicStroke stroke, Paint paint) {
+        return new StrokeBorder(stroke, paint);
+    }
+
+//// DashedBorder //////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+    private static Border sharedDashedBorder;
+
+    /**
+     * Creates a dashed border of the specified {@code paint}.
+     * If the specified {@code paint} is {@code null},
+     * the component's foreground color will be used to render the border.
+     * The width of a dash line is equal to {@code 1}.
+     * The relative length of a dash line and
+     * the relative spacing between dash lines are equal to {@code 1}.
+     * A dash line is not rounded.
+     *
+     * @param paint  the {@link Paint} object used to generate a color
+     * @return the {@code Border} object
+     *
+     * @since 1.7
+     */
+    public static Border createDashedBorder(Paint paint) {
+        return createDashedBorder(paint, 1.0f, 1.0f, 1.0f, false);
+    }
+
+    /**
+     * Creates a dashed border of the specified {@code paint},
+     * relative {@code length}, and relative {@code spacing}.
+     * If the specified {@code paint} is {@code null},
+     * the component's foreground color will be used to render the border.
+     * The width of a dash line is equal to {@code 1}.
+     * A dash line is not rounded.
+     *
+     * @param paint    the {@link Paint} object used to generate a color
+     * @param length   the relative length of a dash line
+     * @param spacing  the relative spacing between dash lines
+     * @return the {@code Border} object
+     *
+     * @throws IllegalArgumentException if the specified {@code length} is less than {@code 1}, or
+     *                                  if the specified {@code spacing} is less than {@code 0}
+     * @since 1.7
+     */
+    public static Border createDashedBorder(Paint paint, float length, float spacing) {
+        return createDashedBorder(paint, 1.0f, length, spacing, false);
+    }
+
+    /**
+     * Creates a dashed border of the specified {@code paint}, {@code thickness},
+     * line shape, relative {@code length}, and relative {@code spacing}.
+     * If the specified {@code paint} is {@code null},
+     * the component's foreground color will be used to render the border.
+     *
+     * @param paint      the {@link Paint} object used to generate a color
+     * @param thickness  the width of a dash line
+     * @param length     the relative length of a dash line
+     * @param spacing    the relative spacing between dash lines
+     * @param rounded    whether or not line ends should be round
+     * @return the {@code Border} object
+     *
+     * @throws IllegalArgumentException if the specified {@code thickness} is less than {@code 1}, or
+     *                                  if the specified {@code length} is less than {@code 1}, or
+     *                                  if the specified {@code spacing} is less than {@code 0}
+     * @since 1.7
+     */
+    public static Border createDashedBorder(Paint paint, float thickness, float length, float spacing, boolean rounded) {
+        boolean shared = !rounded && (paint == null) && (thickness == 1.0f) && (length == 1.0f) && (spacing == 1.0f);
+        if (shared && (sharedDashedBorder != null)) {
+            return sharedDashedBorder;
+        }
+        if (thickness < 1.0f) {
+            throw new IllegalArgumentException("thickness is less than 1");
+        }
+        if (length < 1.0f) {
+            throw new IllegalArgumentException("length is less than 1");
+        }
+        if (spacing < 0.0f) {
+            throw new IllegalArgumentException("spacing is less than 0");
+        }
+        int cap = rounded ? BasicStroke.CAP_ROUND : BasicStroke.CAP_SQUARE;
+        int join = rounded ? BasicStroke.JOIN_ROUND : BasicStroke.JOIN_MITER;
+        float[] array = { thickness * (length - 1.0f), thickness * (spacing + 1.0f) };
+        Border border = createStrokeBorder(new BasicStroke(thickness, cap, join, thickness * 2.0f, array, 0.0f), paint);
+        if (shared) {
+            sharedDashedBorder = border;
+        }
+        return border;
+    }
 }
--- a/src/share/classes/javax/swing/DebugGraphics.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/DebugGraphics.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1322,13 +1322,11 @@
     }
 
     String toShortString() {
-        StringBuffer buffer = new StringBuffer("Graphics" + (isDrawingBuffer() ? "<B>" : "") + "(" + graphicsID + "-" + debugOptions + ")");
-        return buffer.toString();
+        return "Graphics" + (isDrawingBuffer() ? "<B>" : "") + "(" + graphicsID + "-" + debugOptions + ")";
     }
 
     String pointToString(int x, int y) {
-        StringBuffer buffer = new StringBuffer("(" + x + ", " + y + ")");
-        return buffer.toString();
+        return "(" + x + ", " + y + ")";
     }
 
     /** Enables/disables diagnostic information about every graphics
--- a/src/share/classes/javax/swing/JComponent.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/JComponent.java	Thu Nov 11 18:46:02 2010 -0800
@@ -4783,21 +4783,11 @@
      * @param y  the y value of the dirty region
      * @param width  the width of the dirty region
      * @param height  the height of the dirty region
+     * @see #isPaintingOrigin()
      * @see java.awt.Component#isShowing
      * @see RepaintManager#addDirtyRegion
      */
     public void repaint(long tm, int x, int y, int width, int height) {
-        Container p = this;
-        while ((p = p.getParent()) instanceof JComponent) {
-            JComponent jp = (JComponent) p;
-            if (jp.isPaintingOrigin()) {
-                Rectangle rectangle = SwingUtilities.convertRectangle(
-                        this, new Rectangle(x, y, width, height), jp);
-                jp.repaint(tm,
-                        rectangle.x, rectangle.y, rectangle.width, rectangle.height);
-                return;
-            }
-        }
         RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
     }
 
@@ -4808,6 +4798,7 @@
      * currently pending events have been dispatched.
      *
      * @param  r a <code>Rectangle</code> containing the dirty region
+     * @see #isPaintingOrigin()
      * @see java.awt.Component#isShowing
      * @see RepaintManager#addDirtyRegion
      */
@@ -4912,13 +4903,19 @@
     }
 
     /**
-     * Returns true if a paint triggered on a child component should cause
+     * Returns {@code true} if a paint triggered on a child component should cause
      * painting to originate from this Component, or one of its ancestors.
+     * <p/>
+     * Calling {@link JComponent#repaint} on a Swing component will be delegated to
+     * the first ancestor which {@code isPaintingOrigin()} returns {@true},
+     * if there are any.
+     * <p/>
+     * {@code JComponent} subclasses that need to be repainted when any of their
+     * children are repainted should override this method to return {@code true}.
      *
-     * @return true if painting should originate from this Component or
-     *         one of its ancestors.
-     */
-    boolean isPaintingOrigin() {
+     * @return always returns {@code false}
+     */
+    protected boolean isPaintingOrigin() {
         return false;
     }
 
--- a/src/share/classes/javax/swing/JDialog.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/JDialog.java	Thu Nov 11 18:46:02 2010 -0800
@@ -303,10 +303,9 @@
      * @param modal specifies whether dialog blocks user input to other top-level
      *     windows when shown. If {@code true}, the modality type property is set to
      *     {@code DEFAULT_MODALITY_TYPE}, otherwise the dialog is modeless.
-     * @param gc the {@code GraphicsConfiguration}
-     *     of the target screen device.  If {@code gc} is
-     *     {@code null}, the same
-     *     {@code GraphicsConfiguration} as the owning Frame is used.
+     * @param gc the {@code GraphicsConfiguration} of the target screen device;
+     *     if {@code null}, the default system {@code GraphicsConfiguration}
+     *     is assumed
      * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()}
      *     returns {@code true}.
      * @see java.awt.Dialog.ModalityType
@@ -441,10 +440,9 @@
      * @param modal specifies whether dialog blocks user input to other top-level
      *     windows when shown. If {@code true}, the modality type property is set to
      *     {@code DEFAULT_MODALITY_TYPE}, otherwise the dialog is modeless
-     * @param gc the {@code GraphicsConfiguration}
-     *     of the target screen device.  If {@code gc} is
-     *     {@code null}, the same
-     *     {@code GraphicsConfiguration} as the owning Dialog is used.
+     * @param gc the {@code GraphicsConfiguration} of the target screen device;
+     *     if {@code null}, the default system {@code GraphicsConfiguration}
+     *     is assumed
      * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()}
      *     returns {@code true}.
      * @see java.awt.Dialog.ModalityType
@@ -612,10 +610,8 @@
      *     windows when shown. {@code null} value and unsupported modality
      *     types are equivalent to {@code MODELESS}
      * @param gc the {@code GraphicsConfiguration} of the target screen device;
-     *     if {@code null}, the {@code GraphicsConfiguration} from the owning
-     *     window is used; if {@code owner} is also {@code null}, the
-     *     system default {@code GraphicsConfiguration} is assumed
-     *
+     *     if {@code null}, the default system {@code GraphicsConfiguration}
+     *     is assumed
      * @throws IllegalArgumentException
      *     if the {@code owner} is not an instance of {@link java.awt.Dialog Dialog}
      *     or {@link java.awt.Frame Frame}
--- a/src/share/classes/javax/swing/JLayer.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/JLayer.java	Thu Nov 11 18:46:02 2010 -0800
@@ -384,7 +384,7 @@
      * @return true
      * @see JComponent#isPaintingOrigin()
      */
-    boolean isPaintingOrigin() {
+    protected boolean isPaintingOrigin() {
         return true;
     }
 
--- a/src/share/classes/javax/swing/JViewport.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/JViewport.java	Thu Nov 11 18:46:02 2010 -0800
@@ -637,14 +637,14 @@
     }
 
     /**
-     * Returns true if scroll mode is a BACKINGSTORE_SCROLL_MODE to cause
-     * painting to originate from <code>JViewport</code>, or one of its
-     * ancestors. Otherwise returns false.
+     * Returns true if scroll mode is a {@code BACKINGSTORE_SCROLL_MODE} to cause
+     * painting to originate from {@code JViewport}, or one of its
+     * ancestors. Otherwise returns {@code false}.
      *
-     * @return true if if scroll mode is a BACKINGSTORE_SCROLL_MODE.
+     * @return true if if scroll mode is a {@code BACKINGSTORE_SCROLL_MODE}.
      * @see JComponent#isPaintingOrigin()
      */
-    boolean isPaintingOrigin() {
+    protected boolean isPaintingOrigin() {
         return scrollMode == BACKINGSTORE_SCROLL_MODE;
     }
 
--- a/src/share/classes/javax/swing/RepaintManager.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/RepaintManager.java	Thu Nov 11 18:46:02 2010 -0800
@@ -438,6 +438,7 @@
      * @param y Y coordinate of the region to repaint
      * @param w Width of the region to repaint
      * @param h Height of the region to repaint
+     * @see JComponent#isPaintingOrigin()
      * @see JComponent#repaint
      */
     public void addDirtyRegion(JComponent c, int x, int y, int w, int h)
@@ -447,6 +448,16 @@
             delegate.addDirtyRegion(c, x, y, w, h);
             return;
         }
+        Container p = c;
+        while ((p = p.getParent()) instanceof JComponent) {
+            JComponent jp = (JComponent) p;
+            if (jp.isPaintingOrigin()) {
+                Rectangle rectangle = SwingUtilities.convertRectangle(
+                        c, new Rectangle(x, y, w, h), jp);
+                jp.repaint(0, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+                return;
+            }
+        }
         addDirtyRegion0(c, x, y, w, h);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/javax/swing/border/StrokeBorder.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package javax.swing.border;
+
+import java.awt.BasicStroke;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Paint;
+import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
+import java.beans.ConstructorProperties;
+
+/**
+ * A class which implements a border of an arbitrary stroke.
+ * <p>
+ * <strong>Warning:</strong>
+ * Serialized objects of this class will not be compatible with
+ * future Swing releases. The current serialization support is
+ * appropriate for short term storage or RMI
+ * between applications running the same version of Swing.
+ * As of 1.4, support for long term storage of all JavaBeans&trade;
+ * has been added to the <code>java.beans</code> package.
+ * Please see {@link java.beans.XMLEncoder}.
+ *
+ * @author Sergey A. Malenkov
+ *
+ * @since 1.7
+ */
+public class StrokeBorder extends AbstractBorder {
+    private final BasicStroke stroke;
+    private final Paint paint;
+
+    /**
+     * Creates a border of the specified {@code stroke}.
+     * The component's foreground color will be used to render the border.
+     *
+     * @param stroke  the {@link BasicStroke} object used to stroke a shape
+     *
+     * @throws NullPointerException if the specified {@code stroke} is {@code null}
+     */
+    public StrokeBorder(BasicStroke stroke) {
+        this(stroke, null);
+    }
+
+    /**
+     * Creates a border of the specified {@code stroke} and {@code paint}.
+     * If the specified {@code paint} is {@code null},
+     * the component's foreground color will be used to render the border.
+     *
+     * @param stroke  the {@link BasicStroke} object used to stroke a shape
+     * @param paint   the {@link Paint} object used to generate a color
+     *
+     * @throws NullPointerException if the specified {@code stroke} is {@code null}
+     */
+    @ConstructorProperties({ "stroke", "paint" })
+    public StrokeBorder(BasicStroke stroke, Paint paint) {
+        if (stroke == null) {
+            throw new NullPointerException("border's stroke");
+        }
+        this.stroke = stroke;
+        this.paint = paint;
+    }
+
+    /**
+     * Paints the border for the specified component
+     * with the specified position and size.
+     *
+     * @param c       the component for which this border is being painted
+     * @param g       the paint graphics
+     * @param x       the x position of the painted border
+     * @param y       the y position of the painted border
+     * @param width   the width of the painted border
+     * @param height  the height of the painted border
+     *
+     * @throws NullPointerException if the specified {@code c} or {@code g} are {@code null}
+     */
+    @Override
+    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+        float size = this.stroke.getLineWidth();
+        if (size > 0.0f) {
+            g = g.create();
+            if (g instanceof Graphics2D) {
+                Graphics2D g2d = (Graphics2D) g;
+                g2d.setStroke(this.stroke);
+                g2d.setPaint(this.paint != null ? this.paint : c.getForeground());
+                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                                     RenderingHints.VALUE_ANTIALIAS_ON);
+                g2d.draw(new Rectangle2D.Float(x + size / 2, y + size / 2, width - size, height - size));
+            }
+            g.dispose();
+        }
+    }
+
+    /**
+     * Reinitializes the {@code insets} parameter
+     * with this border's current insets.
+     * All insets are equal to the line width of the stroke.
+     *
+     * @param c       the component for which this border insets value applies
+     * @param insets  the {@code Insets} object to be reinitialized
+     * @return the reinitialized {@code insets} parameter
+     *
+     * @throws NullPointerException if the specified {@code insets} is {@code null}
+     */
+    @Override
+    public Insets getBorderInsets(Component c, Insets insets) {
+        int size = (int) Math.ceil(this.stroke.getLineWidth());
+        insets.set(size, size, size, size);
+        return insets;
+    }
+
+    /**
+     * Returns the {@link BasicStroke} object used to stroke a shape
+     * during the border rendering.
+     *
+     * @return the {@link BasicStroke} object
+     */
+    public BasicStroke getStroke() {
+        return this.stroke;
+    }
+
+    /**
+     * Returns the {@link Paint} object used to generate a color
+     * during the border rendering.
+     *
+     * @return the {@link Paint} object or {@code null}
+     *         if the {@code paint} parameter is not set
+     */
+    public Paint getPaint() {
+        return this.paint;
+    }
+}
--- a/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java	Thu Nov 11 18:46:02 2010 -0800
@@ -362,6 +362,14 @@
      * @since 1.6
      */
     public int getBaseline(JComponent c, int width, int height) {
+        if (c == null) {
+            throw new NullPointerException("Component must be non-null");
+        }
+
+        if (width < 0 || height < 0) {
+            throw new IllegalArgumentException("Width and height must be >= 0");
+        }
+
         JViewport viewport = scrollpane.getViewport();
         Insets spInsets = scrollpane.getInsets();
         int y = spInsets.top;
--- a/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java	Thu Nov 11 18:46:02 2010 -0800
@@ -115,10 +115,7 @@
         return new SynthTabbedPaneUI();
     }
 
-    private SynthTabbedPaneUI() {
-    }
-
-    private boolean scrollableTabLayoutEnabled() {
+     private boolean scrollableTabLayoutEnabled() {
         return (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT);
     }
 
--- a/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/table/DefaultTableCellRenderer.java	Thu Nov 11 18:46:02 2010 -0800
@@ -186,6 +186,9 @@
      */
     public Component getTableCellRendererComponent(JTable table, Object value,
                           boolean isSelected, boolean hasFocus, int row, int column) {
+        if (table == null) {
+            return this;
+        }
 
         Color fg = null;
         Color bg = null;
--- a/src/share/classes/javax/swing/text/DefaultCaret.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/DefaultCaret.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1334,13 +1334,13 @@
                     && component.getClientProperty("JPasswordField.cutCopyAllowed") !=
                     Boolean.TRUE) {
                     //fix for 4793761
-                    StringBuffer txt = null;
+                    StringBuilder txt = null;
                     char echoChar = ((JPasswordField)component).getEchoChar();
                     int p0 = Math.min(getDot(), getMark());
                     int p1 = Math.max(getDot(), getMark());
                     for (int i = p0; i < p1; i++) {
                         if (txt == null) {
-                            txt = new StringBuffer();
+                            txt = new StringBuilder();
                         }
                         txt.append(echoChar);
                     }
@@ -1675,7 +1675,6 @@
                 }
                 return;
             }
-            int adjust = 0;
             int offset = e.getOffset();
             int length = e.getLength();
             int newDot = dot;
@@ -1759,7 +1758,6 @@
             }
             int offs0 = e.getOffset();
             int offs1 = offs0 + e.getLength();
-            int adjust = 0;
             int newDot = dot;
             boolean adjustDotBias = false;
             int newMark = mark;
--- a/src/share/classes/javax/swing/text/DefaultStyledDocument.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/DefaultStyledDocument.java	Thu Nov 11 18:46:02 2010 -0800
@@ -132,7 +132,7 @@
             // install the content
             Content c = getContent();
             int n = data.length;
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
             for (int i = 0; i < n; i++) {
                 ElementSpec es = data[i];
                 if (es.getLength() > 0) {
@@ -191,7 +191,7 @@
             // install the content
             Content c = getContent();
             int n = data.length;
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
             for (int i = 0; i < n; i++) {
                 ElementSpec es = data[i];
                 if (es.getLength() > 0) {
--- a/src/share/classes/javax/swing/text/InternationalFormatter.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/InternationalFormatter.java	Thu Nov 11 18:46:02 2010 -0800
@@ -30,7 +30,6 @@
 import java.text.AttributedCharacterIterator.Attribute;
 import java.util.*;
 import javax.swing.*;
-import javax.swing.text.*;
 
 /**
  * <code>InternationalFormatter</code> extends <code>DefaultFormatter</code>,
@@ -875,7 +874,6 @@
                     (f instanceof AttributedCharacterIterator.Attribute)) {
             AttributedCharacterIterator.Attribute field =
                                    (AttributedCharacterIterator.Attribute)f;
-            int index = 0;
 
             iterator.first();
             while (iterator.getIndex() < start) {
--- a/src/share/classes/javax/swing/text/JTextComponent.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/JTextComponent.java	Thu Nov 11 18:46:02 2010 -0800
@@ -35,10 +35,7 @@
 import java.util.Hashtable;
 import java.util.Enumeration;
 import java.util.Vector;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
 
 import java.util.concurrent.*;
 
@@ -4058,7 +4055,7 @@
 
     private static final Object KEYMAP_TABLE =
         new StringBuilder("JTextComponent_KeymapTable");
-    private JTextComponent editor;
+
     //
     // member variables used for on-the-spot input method
     // editing style support
@@ -4748,14 +4745,14 @@
                         processKeyEvent(ke);
                     }
                 } else {
-                    StringBuffer strBuf = new StringBuffer();
+                    StringBuilder strBuf = new StringBuilder();
                     for (char c = text.current(); commitCount > 0;
                          c = text.next(), commitCount--) {
                         strBuf.append(c);
                     }
 
                     // map it to an ActionEvent
-                    mapCommittedTextToAction(new String(strBuf));
+                    mapCommittedTextToAction(strBuf.toString());
                 }
 
                 // Remember latest committed text end index
@@ -4801,7 +4798,7 @@
     private void createComposedTextAttribute(int composedIndex,
                                         AttributedCharacterIterator text) {
         Document doc = getDocument();
-        StringBuffer strBuf = new StringBuffer();
+        StringBuilder strBuf = new StringBuilder();
 
         // create attributed string with no attributes
         for (char c = text.setIndex(composedIndex);
@@ -4809,7 +4806,7 @@
             strBuf.append(c);
         }
 
-        composedTextContent = new String(strBuf);
+        composedTextContent = strBuf.toString();
         composedTextAttribute = new SimpleAttributeSet();
         composedTextAttribute.addAttribute(StyleConstants.ComposedTextAttribute,
                 new AttributedString(text, composedIndex, text.getEndIndex()));
--- a/src/share/classes/javax/swing/text/MaskFormatter.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/MaskFormatter.java	Thu Nov 11 18:46:02 2010 -0800
@@ -29,7 +29,6 @@
 import java.text.*;
 import java.util.*;
 import javax.swing.*;
-import javax.swing.text.*;
 
 /**
  * <code>MaskFormatter</code> is used to format and edit strings. The behavior
@@ -385,7 +384,7 @@
      */
     public String valueToString(Object value) throws ParseException {
         String sValue = (value == null) ? "" : value.toString();
-        StringBuffer result = new StringBuffer();
+        StringBuilder result = new StringBuilder();
         String placeholder = getPlaceholder();
         int[] valueCounter = { 0 };
 
@@ -484,7 +483,7 @@
      * Invokes <code>append</code> on the mask characters in
      * <code>mask</code>.
      */
-    private void append(StringBuffer result, String value, int[] index,
+    private void append(StringBuilder result, String value, int[] index,
                         String placeholder, MaskCharacter[] mask)
                           throws ParseException {
         for (int counter = 0, maxCounter = mask.length;
@@ -611,13 +610,13 @@
      * Removes the literal characters from the passed in string.
      */
     private String stripLiteralChars(String string) {
-        StringBuffer sb = null;
+        StringBuilder sb = null;
         int last = 0;
 
         for (int counter = 0, max = string.length(); counter < max; counter++){
             if (isLiteral(counter)) {
                 if (sb == null) {
-                    sb = new StringBuffer();
+                    sb = new StringBuilder();
                     if (counter > 0) {
                         sb.append(string.substring(0, counter));
                     }
@@ -715,10 +714,10 @@
      */
     boolean canReplace(ReplaceHolder rh) {
         // This method is rather long, but much of the burden is in
-        // maintaining a String and swapping to a StringBuffer only if
+        // maintaining a String and swapping to a StringBuilder only if
         // absolutely necessary.
         if (!getAllowsInvalid()) {
-            StringBuffer replace = null;
+            StringBuilder replace = null;
             String text = rh.text;
             int tl = (text != null) ? text.length() : 0;
 
@@ -737,7 +736,7 @@
                     char aChar = text.charAt(textIndex);
                     if (aChar != getCharacter(rh.offset + counter, aChar)) {
                         if (replace == null) {
-                            replace = new StringBuffer();
+                            replace = new StringBuilder();
                             if (textIndex > 0) {
                                 replace.append(text.substring(0, textIndex));
                             }
@@ -758,7 +757,7 @@
                         }
                     }
                     else if (textIndex > 0) {
-                        replace = new StringBuffer(max);
+                        replace = new StringBuilder(max);
                         replace.append(text.substring(0, textIndex));
                         replace.append(getLiteral(rh.offset + counter));
                         if (textIndex < tl) {
@@ -780,7 +779,7 @@
                 else if (textIndex >= tl) {
                     // placeholder
                     if (replace == null) {
-                        replace = new StringBuffer();
+                        replace = new StringBuilder();
                         if (text != null) {
                             replace.append(text);
                         }
@@ -863,7 +862,7 @@
          * Appends the necessary character in <code>formatting</code> at
          * <code>index</code> to <code>buff</code>.
          */
-        public void append(StringBuffer buff, String formatting, int[] index,
+        public void append(StringBuilder buff, String formatting, int[] index,
                            String placeholder)
                           throws ParseException {
             boolean inString = index[0] < formatting.length();
--- a/src/share/classes/javax/swing/text/NumberFormatter.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/NumberFormatter.java	Thu Nov 11 18:46:02 2010 -0800
@@ -27,7 +27,6 @@
 import java.lang.reflect.*;
 import java.text.*;
 import java.util.*;
-import javax.swing.text.*;
 
 /**
  * <code>NumberFormatter</code> subclasses <code>InternationalFormatter</code>
@@ -132,7 +131,7 @@
         DecimalFormatSymbols dfs = getDecimalFormatSymbols();
 
         if (dfs != null) {
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
 
             sb.append(dfs.getCurrencySymbol());
             sb.append(dfs.getDecimalSeparator());
@@ -240,13 +239,6 @@
     }
 
     /**
-     */
-    private boolean isValidInsertionCharacter(char aChar) {
-        return (Character.isDigit(aChar) || specialChars.indexOf(aChar) != -1);
-    }
-
-
-    /**
      * Subclassed to return false if <code>text</code> contains in an invalid
      * character to insert, that is, it is not a digit
      * (<code>Character.isDigit()</code>) and
@@ -403,28 +395,6 @@
     }
 
     /**
-     * Returns true if the range offset to length identifies the only
-     * integer field.
-     */
-    private boolean isOnlyIntegerField(int offset, int length) {
-        if (isValidMask()) {
-            int start = getAttributeStart(NumberFormat.Field.INTEGER);
-
-            if (start != -1) {
-                AttributedCharacterIterator iterator = getIterator();
-
-                iterator.setIndex(start);
-                if (offset > start || iterator.getRunLimit(
-                    NumberFormat.Field.INTEGER) > (offset + length)) {
-                    return false;
-                }
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * Invoked to toggle the sign. For this to work the value class
      * must have a single arg constructor that takes a String.
      */
--- a/src/share/classes/javax/swing/text/PlainDocument.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/PlainDocument.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,7 +25,6 @@
 package javax.swing.text;
 
 import java.util.Vector;
-import javax.swing.event.*;
 
 /**
  * A plain document that maintains no character attributes.  The
@@ -118,7 +117,7 @@
         Object filterNewlines = getProperty("filterNewlines");
         if ((filterNewlines instanceof Boolean) && filterNewlines.equals(Boolean.TRUE)) {
             if ((str != null) && (str.indexOf('\n') >= 0)) {
-                StringBuffer filtered = new StringBuffer(str);
+                StringBuilder filtered = new StringBuilder(str);
                 int n = filtered.length();
                 for (int i = 0; i < n; i++) {
                     if (filtered.charAt(i) == '\n') {
@@ -204,11 +203,9 @@
                 }
             }
             if (hasBreaks) {
-                int rmCount = 1;
                 removed.addElement(rmCandidate);
                 if ((offset + length == rmOffs1) && (lastOffset != rmOffs1) &&
                     ((index+1) < lineMap.getElementCount())) {
-                    rmCount += 1;
                     Element e = lineMap.getElement(index+1);
                     removed.addElement(e);
                     rmOffs1 = e.getEndOffset();
--- a/src/share/classes/javax/swing/text/TabSet.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/TabSet.java	Thu Nov 11 18:46:02 2010 -0800
@@ -199,7 +199,7 @@
      */
     public String toString() {
         int            tabCount = getTabCount();
-        StringBuffer   buffer = new StringBuffer("[ ");
+        StringBuilder buffer = new StringBuilder("[ ");
 
         for(int counter = 0; counter < tabCount; counter++) {
             if(counter > 0)
--- a/src/share/classes/javax/swing/text/html/FormView.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/html/FormView.java	Thu Nov 11 18:46:02 2010 -0800
@@ -362,7 +362,7 @@
      */
     public void actionPerformed(ActionEvent evt) {
         Element element = getElement();
-        StringBuffer dataBuffer = new StringBuffer();
+        StringBuilder dataBuffer = new StringBuilder();
         HTMLDocument doc = (HTMLDocument)getDocument();
         AttributeSet attr = element.getAttributes();
 
@@ -508,7 +508,7 @@
      */
     protected void imageSubmit(String imageData) {
 
-        StringBuffer dataBuffer = new StringBuffer();
+        StringBuilder dataBuffer = new StringBuilder();
         Element elem = getElement();
         HTMLDocument hdoc = (HTMLDocument)elem.getDocument();
         getFormData(dataBuffer);
@@ -589,7 +589,7 @@
      * @param targetElement the element that triggered the
      *                      form submission
      */
-    void getFormData(StringBuffer buffer) {
+    private void getFormData(StringBuilder buffer) {
         Element formE = getFormElement();
         if (formE != null) {
             ElementIterator it = new ElementIterator(formE);
@@ -623,7 +623,7 @@
      * data is loaded in name/value pairs.
      *
      */
-    private void loadElementDataIntoBuffer(Element elem, StringBuffer buffer) {
+    private void loadElementDataIntoBuffer(Element elem, StringBuilder buffer) {
 
         AttributeSet attr = elem.getAttributes();
         String name = (String)attr.getAttribute(HTML.Attribute.NAME);
@@ -692,29 +692,6 @@
             }
             if (path != null && path.length() > 0) {
                 value = path;
-/*
-
-                try {
-                    Reader reader = new BufferedReader(new FileReader(path));
-                    StringBuffer buffer = new StringBuffer();
-                    char[] cBuff = new char[1024];
-                    int read;
-
-                    try {
-                        while ((read = reader.read(cBuff)) != -1) {
-                            buffer.append(cBuff, 0, read);
-                        }
-                    } catch (IOException ioe) {
-                        buffer = null;
-                    }
-                    try {
-                        reader.close();
-                    } catch (IOException ioe) {}
-                    if (buffer != null) {
-                        value = buffer.toString();
-                    }
-                } catch (IOException ioe) {}
-*/
             }
         }
         return value;
@@ -740,7 +717,7 @@
      * form element.  Basically, only items that are selected
      * and have their name attribute set are added to the buffer.
      */
-    private void loadSelectData(AttributeSet attr, StringBuffer buffer) {
+    private void loadSelectData(AttributeSet attr, StringBuilder buffer) {
 
         String name = (String)attr.getAttribute(HTML.Attribute.NAME);
         if (name == null) {
@@ -771,7 +748,7 @@
      * URLEncoder.encode() method before being added to the
      * buffer.
      */
-    private void appendBuffer(StringBuffer buffer, String name, String value) {
+    private void appendBuffer(StringBuilder buffer, String name, String value) {
         if (buffer.length() > 0) {
             buffer.append('&');
         }
--- a/src/share/classes/javax/swing/text/html/MinimalHTMLWriter.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/html/MinimalHTMLWriter.java	Thu Nov 11 18:46:02 2010 -0800
@@ -691,11 +691,11 @@
         if (styleNameMapping == null) {
             return style;
         }
-        StringBuffer sb = null;
+        StringBuilder sb = null;
         for (int counter = style.length() - 1; counter >= 0; counter--) {
             if (!isValidCharacter(style.charAt(counter))) {
                 if (sb == null) {
-                    sb = new StringBuffer(style);
+                    sb = new StringBuilder(style);
                 }
                 sb.setCharAt(counter, 'a');
             }
--- a/src/share/classes/javax/swing/text/html/StyleSheet.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/html/StyleSheet.java	Thu Nov 11 18:46:02 2010 -0800
@@ -998,7 +998,7 @@
     void addRule(String[] selector, AttributeSet declaration,
                  boolean isLinked) {
         int n = selector.length;
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         sb.append(selector[0]);
         for (int counter = 1; counter < n; counter++) {
             sb.append(' ');
--- a/src/share/classes/javax/swing/text/html/parser/Parser.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/html/parser/Parser.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1470,7 +1470,7 @@
      */
     public String parseDTDMarkup() throws IOException {
 
-        StringBuffer strBuff = new StringBuffer();
+        StringBuilder strBuff = new StringBuilder();
         ch = readCh();
         while(true) {
             switch (ch) {
--- a/src/share/classes/javax/swing/text/rtf/AbstractFilter.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/javax/swing/text/rtf/AbstractFilter.java	Thu Nov 11 18:46:02 2010 -0800
@@ -160,7 +160,7 @@
     public void write(byte[] buf, int off, int len)
       throws IOException
     {
-      StringBuffer accumulator = null;
+      StringBuilder accumulator = null;
       while (len > 0) {
         short b = (short)buf[off];
 
@@ -178,7 +178,7 @@
           char ch = translationTable[b];
           if (ch != (char)0) {
             if (accumulator == null)
-              accumulator = new StringBuffer();
+              accumulator = new StringBuilder();
             accumulator.append(ch);
           }
         }
--- a/src/share/classes/sun/dyn/BoundMethodHandle.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/BoundMethodHandle.java	Thu Nov 11 18:46:02 2010 -0800
@@ -48,8 +48,6 @@
     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(IMPL_TOKEN);
 
     // Constructors in this class *must* be package scoped or private.
-    // Exception:  JavaMethodHandle constructors are protected.
-    // (The link between JMH and BMH is temporary.)
 
     /** Bind a direct MH to its receiver (or first ref. argument).
      *  The JVM will pre-dispatch the MH if it is not already static.
@@ -122,55 +120,6 @@
         assert(this instanceof JavaMethodHandle);
     }
 
-    /** Initialize the current object as a Java method handle.
-     */
-    protected BoundMethodHandle(String entryPointName, MethodType type, boolean matchArity) {
-        super(Access.TOKEN, null);
-        MethodHandle entryPoint
-                = findJavaMethodHandleEntryPoint(this.getClass(),
-                                        entryPointName, type, matchArity);
-        MethodHandleImpl.initType(this, entryPoint.type().dropParameterTypes(0, 1));
-        this.argument = this; // kludge; get rid of
-        this.vmargslot = this.type().parameterSlotDepth(0);
-        initTarget(entryPoint, 0);
-        assert(this instanceof JavaMethodHandle);
-    }
-
-    private static
-    MethodHandle findJavaMethodHandleEntryPoint(Class<?> caller,
-                                                String name,
-                                                MethodType type,
-                                                boolean matchArity) {
-        if (matchArity)  type.getClass();  // elicit NPE
-        List<MemberName> methods = IMPL_NAMES.getMethods(caller, true, name, null, caller);
-        MethodType foundType = null;
-        MemberName foundMethod = null;
-        for (MemberName method : methods) {
-            if (method.getDeclaringClass() == MethodHandle.class)
-                continue;  // ignore methods inherited from MH class itself
-            MethodType mtype = method.getMethodType();
-            if (type != null && type.parameterCount() != mtype.parameterCount())
-                continue;
-            else if (foundType == null)
-                foundType = mtype;
-            else if (foundType != mtype)
-                throw newIllegalArgumentException("more than one method named "+name+" in "+caller.getName());
-            // discard overrides
-            if (foundMethod == null)
-                foundMethod = method;
-            else if (foundMethod.getDeclaringClass().isAssignableFrom(method.getDeclaringClass()))
-                foundMethod = method;
-        }
-        if (foundMethod == null)
-            throw newIllegalArgumentException("no method named "+name+" in "+caller.getName());
-        MethodHandle entryPoint = MethodHandleImpl.findMethod(IMPL_TOKEN, foundMethod, true, caller);
-        if (type != null) {
-            MethodType epType = type.insertParameterTypes(0, entryPoint.type().parameterType(0));
-            entryPoint = MethodHandles.convertArguments(entryPoint, epType);
-        }
-        return entryPoint;
-    }
-
     /** Make sure the given {@code argument} can be used as {@code argnum}-th
      *  parameter of the given method handle {@code mh}, which must be a reference.
      *  <p>
--- a/src/share/classes/sun/dyn/CallSiteImpl.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/CallSiteImpl.java	Thu Nov 11 18:46:02 2010 -0800
@@ -26,6 +26,7 @@
 package sun.dyn;
 
 import java.dyn.*;
+import static sun.dyn.MemberName.uncaughtException;
 
 /**
  * Parts of CallSite known to the JVM.
@@ -49,18 +50,21 @@
         }
         CallSite site;
         try {
-            if (bootstrapMethod.type().parameterCount() == 3)
-                site = bootstrapMethod.<CallSite>invokeExact(caller, name, type);
-            else if (bootstrapMethod.type().parameterCount() == 4)
-                site = bootstrapMethod.<CallSite>invokeExact(caller, name, type,
-                                                             !(info instanceof java.lang.annotation.Annotation[]) ? null
-                                                             : (java.lang.annotation.Annotation[]) info);
+            Object binding;
+            if (false)  // switch when invokeGeneric works
+                binding = bootstrapMethod.invokeGeneric(caller, name, type);
             else
-                throw new InternalError("bad BSM: "+bootstrapMethod);
-            if (!(site instanceof CallSite))
-                throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
-            PRIVATE_INITIALIZE_CALL_SITE.<void>invokeExact(site,
-                                                           name, type,
+                binding = bootstrapMethod.invokeVarargs(new Object[]{ caller, name, type });
+            //System.out.println("BSM for "+name+type+" => "+binding);
+            if (binding instanceof CallSite) {
+                site = (CallSite) binding;
+            } else if (binding instanceof MethodHandleProvider) {
+                MethodHandle target = ((MethodHandleProvider) binding).asMethodHandle();
+                site = new ConstantCallSite(target);
+            } else {
+                throw new ClassCastException("bootstrap method failed to produce a MethodHandle or CallSite");
+            }
+            PRIVATE_INITIALIZE_CALL_SITE.<void>invokeExact(site, name, type,
                                                            callerMethod, callerBCI);
             assert(site.getTarget() != null);
             assert(site.getTarget().type().equals(type));
@@ -77,11 +81,18 @@
 
     // This method is private in CallSite because it touches private fields in CallSite.
     // These private fields (vmmethod, vmindex) are specific to the JVM.
-    private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
+    private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE;
+    static {
+        try {
+            PRIVATE_INITIALIZE_CALL_SITE =
             MethodHandleImpl.IMPL_LOOKUP.findVirtual(CallSite.class, "initializeFromJVM",
                 MethodType.methodType(void.class,
                                       String.class, MethodType.class,
                                       MemberName.class, int.class));
+        } catch (NoAccessException ex) {
+            throw uncaughtException(ex);
+        }
+    }
 
     public static void setCallSiteTarget(Access token, CallSite site, MethodHandle target) {
         Access.check(token);
--- a/src/share/classes/sun/dyn/FilterGeneric.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/FilterGeneric.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,12 +25,8 @@
 
 package sun.dyn;
 
-import java.dyn.JavaMethodHandle;
-import java.dyn.MethodHandle;
-import java.dyn.MethodType;
-import java.dyn.NoAccessException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
+import java.dyn.*;
+import java.lang.reflect.*;
 import static sun.dyn.MemberName.newIllegalArgumentException;
 
 /**
@@ -119,7 +115,7 @@
 
     static MethodHandle make(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
         FilterGeneric fgen = of(kind, pos, filter.type(), target.type());
-        return fgen.makeInstance(kind, pos, filter, target);
+        return fgen.makeInstance(kind, pos, filter, target).asMethodHandle();
     }
 
     /** Return the adapter information for this target and filter type. */
--- a/src/share/classes/sun/dyn/FilterOneArgument.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/FilterOneArgument.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,9 +25,8 @@
 
 package sun.dyn;
 
-import java.dyn.JavaMethodHandle;
-import java.dyn.MethodHandle;
-import java.dyn.MethodType;
+import java.dyn.*;
+import static sun.dyn.MemberName.uncaughtException;
 
 /**
  * Unary function composition, useful for many small plumbing jobs.
@@ -51,8 +50,16 @@
         return target.invokeExact(filteredArgument);
     }
 
-    private static final MethodHandle INVOKE =
-        MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke", MethodType.genericMethodType(1));
+    private static final MethodHandle INVOKE;
+    static {
+        try {
+            INVOKE =
+                MethodHandleImpl.IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
+                                                         MethodType.genericMethodType(1));
+        } catch (NoAccessException ex) {
+            throw uncaughtException(ex);
+        }
+    }
 
     protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
         super(INVOKE);
--- a/src/share/classes/sun/dyn/FromGeneric.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/FromGeneric.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,15 +25,9 @@
 
 package sun.dyn;
 
-import java.dyn.JavaMethodHandle;
-import java.dyn.MethodHandle;
-import java.dyn.MethodHandles;
-import java.dyn.MethodType;
-import java.dyn.NoAccessException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import sun.dyn.util.ValueConversions;
-import sun.dyn.util.Wrapper;
+import java.dyn.*;
+import java.lang.reflect.*;
+import sun.dyn.util.*;
 
 /**
  * Adapters which mediate between incoming calls which are generic
--- a/src/share/classes/sun/dyn/Invokers.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/Invokers.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,10 +25,7 @@
 
 package sun.dyn;
 
-import java.dyn.MethodHandle;
-import java.dyn.MethodHandles;
-import java.dyn.MethodType;
-
+import java.dyn.*;
 
 /**
  * Construction and caching of often-used invokers.
@@ -63,8 +60,11 @@
     public MethodHandle exactInvoker() {
         MethodHandle invoker = exactInvoker;
         if (invoker != null)  return invoker;
-        invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invoke", targetType);
-        if (invoker == null)  throw new InternalError("JVM cannot find invoker for "+targetType);
+        try {
+            invoker = MethodHandleImpl.IMPL_LOOKUP.findVirtual(MethodHandle.class, "invoke", targetType);
+        } catch (NoAccessException ex) {
+            throw new InternalError("JVM cannot find invoker for "+targetType);
+        }
         assert(invokerType(targetType) == invoker.type());
         exactInvoker = invoker;
         return invoker;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/dyn/JavaMethodHandle.java	Thu Nov 11 18:46:02 2010 -0800
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2008, 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 sun.dyn;
+
+import java.dyn.*;
+import sun.dyn.Access;
+
+/**
+ * A Java method handle is a deprecated proposal for extending
+ * the basic method handle type with additional
+ * programmer defined methods and fields.
+ * Its behavior as a method handle is determined at instance creation time,
+ * by providing the new instance with an "entry point" method handle
+ * to handle calls.  This entry point must accept a leading argument
+ * whose type is the Java method handle itself or a supertype, and the
+ * entry point is always called with the Java method handle itself as
+ * the first argument.  This is similar to ordinary virtual methods, which also
+ * accept the receiver object {@code this} as an implicit leading argument.
+ * The {@code MethodType} of the Java method handle is the same as that
+ * of the entry point method handle, with the leading parameter type
+ * omitted.
+ * <p>
+ * Here is an example of usage, creating a hybrid object/functional datum:
+ * <p><blockquote><pre>
+ * class Greeter extends JavaMethodHandle {
+ *     private String greeting = "hello";
+ *     public void setGreeting(String s) { greeting = s; }
+ *     public void run() { System.out.println(greeting+", "+greetee); }
+ *     private final String greetee;
+ *     Greeter(String greetee) {
+ *         super(RUN); // alternatively, super("run")
+ *         this.greetee = greetee;
+ *     }
+ *     // the entry point function is computed once:
+ *     private static final MethodHandle RUN
+ *         = MethodHandles.lookup().findVirtual(Greeter.class, "run",
+ *               MethodType.make(void.class));
+ * }
+ * // class Main { public static void main(String... av) { ...
+ * Greeter greeter = new Greeter("world");
+ * greeter.run();  // prints "hello, world"
+ * // Statically typed method handle invocation (most direct):
+ * MethodHandle mh = greeter;
+ * mh.&lt;void&gt;invokeExact();  // also prints "hello, world"
+ * // Dynamically typed method handle invocation:
+ * MethodHandles.invokeExact(greeter);  // also prints "hello, world"
+ * greeter.setGreeting("howdy");
+ * mh.invokeExact();  // prints "howdy, world" (object-like mutable behavior)
+ * </pre></blockquote>
+ * <p>
+ * In the example of {@code Greeter}, the method {@code run} provides the entry point.
+ * The entry point need not be a constant value; it may be independently
+ * computed in each call to the constructor.  The entry point does not
+ * even need to be a method on the {@code Greeter} class, though
+ * that is the typical case.
+ * <p>
+ * The entry point may also be provided symbolically, in which case the the
+ * {@code JavaMethodHandle} constructor performs the lookup of the entry point.
+ * This makes it possible to use {@code JavaMethodHandle} to create an anonymous
+ * inner class:
+ * <p><blockquote><pre>
+ * // We can also do this with symbolic names and/or inner classes:
+ * MethodHandles.invokeExact(new JavaMethodHandle("yow") {
+ *     void yow() { System.out.println("yow, world"); }
+ * });
+ * </pre></blockquote>
+ * <p>
+ * Here is similar lower-level code which works in terms of a bound method handle.
+ * <p><blockquote><pre>
+ *     class Greeter {
+ *         public void run() { System.out.println("hello, "+greetee); }
+ *         private final String greetee;
+ *         Greeter(String greetee) { this.greetee = greetee; }
+ *         // the entry point function is computed once:
+ *         private static final MethodHandle RUN
+ *             = MethodHandles.findVirtual(Greeter.class, "run",
+ *                   MethodType.make(void.class));
+ *     }
+ *     // class Main { public static void main(String... av) { ...
+ *     Greeter greeter = new Greeter("world");
+ *     greeter.run();  // prints "hello, world"
+ *     MethodHandle mh = MethodHanndles.insertArgument(Greeter.RUN, 0, greeter);
+ *     mh.invokeExact();  // also prints "hello, world"
+ * </pre></blockquote>
+ * Note that the method handle must be separately created as a view on the base object.
+ * This increases footprint, complexity, and dynamic indirections.
+ * <p>
+ * Here is a pure functional value expressed most concisely as an anonymous inner class:
+ * <p><blockquote><pre>
+ *     // class Main { public static void main(String... av) { ...
+ *     final String greetee = "world";
+ *     MethodHandle greeter = new JavaMethodHandle("run") {
+ *         private void run() { System.out.println("hello, "+greetee); }
+ *     }
+ *     greeter.invokeExact();  // prints "hello, world"
+ * </pre></blockquote>
+ * <p>
+ * Here is an abstract parameterized lvalue, efficiently expressed as a subtype of MethodHandle,
+ * and instantiated as an anonymous class.  The data structure is a handle to 1-D array,
+ * with a specialized index type (long).  It is created by inner class, and uses
+ * signature-polymorphic APIs throughout.
+ * <p><blockquote><pre>
+ *     abstract class AssignableMethodHandle extends JavaMethodHandle {
+ *       private final MethodHandle setter;
+ *       public MethodHandle setter() { return setter; }
+ *       public AssignableMethodHandle(String get, String set) {
+ *         super(get);
+ *         MethodType getType = this.type();
+ *         MethodType setType = getType.insertParameterType(getType.parameterCount(), getType.returnType()).changeReturnType(void.class);
+ *         this.setter = MethodHandles.publicLookup().bind(this, set, setType);
+ *       }
+ *     }
+ *     // class Main { public static void main(String... av) { ...
+ *     final Number[] stuff = { 123, 456 };
+ *     AssignableMethodHandle stuffPtr = new AssignableMethodHandle("get", "set") {
+ *         public Number get(long i)           { return stuff[(int)i]; }
+ *         public void   set(long i, Object x) {        stuff[(int)i] = x; }
+ *     }
+ *     int x = (Integer) stuffPtr.&lt;Number&gt;invokeExact(1L);  // 456
+ *     stuffPtr.setter().&lt;void&gt;invokeExact(0L, (Number) 789);  // replaces 123 with 789
+ * </pre></blockquote>
+ * @see MethodHandle
+ * @deprecated The JSR 292 EG intends to replace {@code JavaMethodHandle} with
+ * an interface-based API for mixing method handle behavior with other classes.
+ * @author John Rose, JSR 292 EG
+ */
+public abstract class JavaMethodHandle
+        // Note: This is an implementation inheritance hack, and will be removed
+        // with a JVM change which moves the required hidden behavior onto this class.
+        extends sun.dyn.BoundMethodHandle
+{
+    private static final Access IMPL_TOKEN = Access.getToken();
+
+    /**
+     * When creating a {@code JavaMethodHandle}, the actual method handle
+     * invocation behavior will be delegated to the specified {@code entryPoint}.
+     * This may be any method handle which can take the newly constructed object
+     * as a leading parameter.
+     * <p>
+     * The method handle type of {@code this} (i.e, the fully constructed object)
+     * will be {@code entryPoint}, minus the leading argument.
+     * The leading argument will be bound to {@code this} on every method
+     * handle invocation.
+     * @param entryPoint the method handle to handle calls
+     */
+    protected JavaMethodHandle(MethodHandle entryPoint) {
+        super(entryPoint);
+    }
+}
--- a/src/share/classes/sun/dyn/MemberName.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/MemberName.java	Thu Nov 11 18:46:02 2010 -0800
@@ -521,6 +521,11 @@
         if (lookupClass != null)  message += ", from " + lookupClass.getName();
         return new NoAccessException(message);
     }
+    public static Error uncaughtException(Exception ex) {
+        Error err = new InternalError("uncaught exception");
+        err.initCause(ex);
+        return err;
+    }
 
     /** Actually making a query requires an access check. */
     public static Factory getFactory(Access token) {
@@ -641,7 +646,7 @@
          *  If lookup fails or access is not permitted, a {@linkplain NoAccessException} is thrown.
          *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
          */
-        public MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass) {
+        public MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass) throws NoAccessException {
             MemberName result = resolveOrNull(m, searchSupers, lookupClass);
             if (result != null)
                 return result;
--- a/src/share/classes/sun/dyn/MethodHandleImpl.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/MethodHandleImpl.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,11 +25,8 @@
 
 package sun.dyn;
 
-import java.dyn.JavaMethodHandle;
-import java.dyn.MethodHandle;
-import java.dyn.MethodHandles;
+import java.dyn.*;
 import java.dyn.MethodHandles.Lookup;
-import java.dyn.MethodType;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import sun.dyn.util.VerifyType;
@@ -46,6 +43,7 @@
 import sun.misc.Unsafe;
 import static sun.dyn.MemberName.newIllegalArgumentException;
 import static sun.dyn.MemberName.newNoAccessException;
+import static sun.dyn.MemberName.uncaughtException;
 
 /**
  * Base class for method handles, containing JVM-specific fields and logic.
@@ -173,7 +171,7 @@
      */
     public static
     MethodHandle findMethod(Access token, MemberName method,
-            boolean doDispatch, Class<?> lookupClass) {
+            boolean doDispatch, Class<?> lookupClass) throws NoAccessException {
         Access.check(token);  // only trusted calls
         MethodType mtype = method.getMethodType();
         if (!method.isStatic()) {
@@ -320,7 +318,7 @@
             try {
                 VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true));
             } catch (NoAccessException ex) {
-                throw new InternalError("");
+                throw uncaughtException(ex);
             }
         }
         // Corresponding generic constructor types:
@@ -416,9 +414,7 @@
                 f = c.getDeclaredField(field.getName());
                 return unsafe.staticFieldBase(f);
             } catch (Exception ee) {
-                Error e = new InternalError();
-                e.initCause(ee);
-                throw e;
+                throw uncaughtException(ee);
             }
         }
 
@@ -473,10 +469,8 @@
             MethodHandle mh;
             try {
                 mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
-            } catch (NoAccessException ee) {
-                Error e = new InternalError("name,type="+name+type);
-                e.initCause(ee);
-                throw e;
+            } catch (NoAccessException ex) {
+                throw uncaughtException(ex);
             }
             if (evclass != vclass || (!isStatic && ecclass != cclass)) {
                 MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
@@ -543,10 +537,8 @@
             MethodHandle mh;
             try {
                 mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
-            } catch (NoAccessException ee) {
-                Error e = new InternalError("name,type="+name+type);
-                e.initCause(ee);
-                throw e;
+            } catch (NoAccessException ex) {
+                throw uncaughtException(ex);
             }
             if (caclass != null) {
                 MethodType strongType = FieldAccessor.atype(caclass, isSetter);
@@ -1031,7 +1023,7 @@
             try {
                 VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true));
             } catch (NoAccessException ex) {
-                throw new InternalError("");
+                throw uncaughtException(ex);
             }
         }
     }
@@ -1167,7 +1159,7 @@
             try {
                 VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithCatch.class, "invoke_V", MethodType.genericMethodType(0, true));
             } catch (NoAccessException ex) {
-                throw new InternalError("");
+                throw uncaughtException(ex);
             }
         }
     }
@@ -1207,9 +1199,16 @@
         return AdapterMethodHandle.makeRetypeRaw(token, type, THROW_EXCEPTION);
     }
 
-    static final MethodHandle THROW_EXCEPTION
+    static final MethodHandle THROW_EXCEPTION;
+    static {
+        try {
+            THROW_EXCEPTION
             = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
                     MethodType.methodType(Empty.class, Throwable.class));
+        } catch (NoAccessException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
     static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
 
     public static String getNameString(Access token, MethodHandle target) {
--- a/src/share/classes/sun/dyn/MethodHandleNatives.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/MethodHandleNatives.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,9 +25,7 @@
 
 package sun.dyn;
 
-import java.dyn.CallSite;
-import java.dyn.MethodHandle;
-import java.dyn.MethodType;
+import java.dyn.*;
 import java.dyn.MethodHandles.Lookup;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
@@ -324,18 +322,24 @@
      */
     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
                                                  Class<?> defc, String name, Object type) {
-        Lookup lookup = IMPL_LOOKUP.in(callerClass);
-        switch (refKind) {
-        case REF_getField:          return lookup.findGetter(       defc, name, (Class<?>)   type );
-        case REF_getStatic:         return lookup.findStaticGetter( defc, name, (Class<?>)   type );
-        case REF_putField:          return lookup.findSetter(       defc, name, (Class<?>)   type );
-        case REF_putStatic:         return lookup.findStaticSetter( defc, name, (Class<?>)   type );
-        case REF_invokeVirtual:     return lookup.findVirtual(      defc, name, (MethodType) type );
-        case REF_invokeStatic:      return lookup.findStatic(       defc, name, (MethodType) type );
-        case REF_invokeSpecial:     return lookup.findSpecial(      defc, name, (MethodType) type, callerClass );
-        case REF_newInvokeSpecial:  return lookup.findConstructor(  defc,       (MethodType) type );
-        case REF_invokeInterface:   return lookup.findVirtual(      defc, name, (MethodType) type );
+        try {
+            Lookup lookup = IMPL_LOOKUP.in(callerClass);
+            switch (refKind) {
+            case REF_getField:          return lookup.findGetter(       defc, name, (Class<?>)   type );
+            case REF_getStatic:         return lookup.findStaticGetter( defc, name, (Class<?>)   type );
+            case REF_putField:          return lookup.findSetter(       defc, name, (Class<?>)   type );
+            case REF_putStatic:         return lookup.findStaticSetter( defc, name, (Class<?>)   type );
+            case REF_invokeVirtual:     return lookup.findVirtual(      defc, name, (MethodType) type );
+            case REF_invokeStatic:      return lookup.findStatic(       defc, name, (MethodType) type );
+            case REF_invokeSpecial:     return lookup.findSpecial(      defc, name, (MethodType) type, callerClass );
+            case REF_newInvokeSpecial:  return lookup.findConstructor(  defc,       (MethodType) type );
+            case REF_invokeInterface:   return lookup.findVirtual(      defc, name, (MethodType) type );
+            }
+            throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
+        } catch (NoAccessException ex) {
+            Error err = new IncompatibleClassChangeError();
+            err.initCause(ex);
+            throw err;
         }
-        throw new IllegalArgumentException("bad MethodHandle constant "+name+" : "+type);
     }
 }
--- a/src/share/classes/sun/dyn/SpreadGeneric.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/SpreadGeneric.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,11 +25,7 @@
 
 package sun.dyn;
 
-import java.dyn.JavaMethodHandle;
-import java.dyn.MethodHandle;
-import java.dyn.MethodHandles;
-import java.dyn.MethodType;
-import java.dyn.NoAccessException;
+import java.dyn.*;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
--- a/src/share/classes/sun/dyn/ToGeneric.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/ToGeneric.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,11 +25,7 @@
 
 package sun.dyn;
 
-import java.dyn.JavaMethodHandle;
-import java.dyn.MethodHandle;
-import java.dyn.MethodHandles;
-import java.dyn.MethodType;
-import java.dyn.NoAccessException;
+import java.dyn.*;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import sun.dyn.util.ValueConversions;
--- a/src/share/classes/sun/dyn/util/ValueConversions.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/dyn/util/ValueConversions.java	Thu Nov 11 18:46:02 2010 -0800
@@ -34,6 +34,7 @@
 import sun.dyn.Access;
 import sun.dyn.AdapterMethodHandle;
 import sun.dyn.MethodHandleImpl;
+import static sun.dyn.MemberName.uncaughtException;
 
 public class ValueConversions {
     private static final Access IMPL_TOKEN = Access.getToken();
@@ -148,11 +149,16 @@
         // look up the method
         String name = "unbox" + wrap.simpleName() + (raw ? "Raw" : "");
         MethodType type = unboxType(wrap, raw);
-        if (!exact)
-            // actually, type is wrong; the Java method takes Object
-            mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
-        else
+        if (!exact) {
+            try {
+                // actually, type is wrong; the Java method takes Object
+                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type.erase());
+            } catch (NoAccessException ex) {
+                mh = null;
+            }
+        } else {
             mh = retype(type, unbox(wrap, !exact, raw));
+        }
         if (mh != null) {
             cache.put(wrap, mh);
             return mh;
@@ -280,10 +286,15 @@
         // look up the method
         String name = "box" + wrap.simpleName() + (raw ? "Raw" : "");
         MethodType type = boxType(wrap, raw);
-        if (exact)
-            mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
-        else
+        if (exact) {
+            try {
+                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
+            } catch (NoAccessException ex) {
+                mh = null;
+            }
+        } else {
             mh = retype(type.erase(), box(wrap, !exact, raw));
+        }
         if (mh != null) {
             cache.put(wrap, mh);
             return mh;
@@ -394,10 +405,15 @@
         // look up the method
         String name = "reboxRaw" + wrap.simpleName();
         MethodType type = reboxType(wrap);
-        if (exact)
-            mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
-        else
+        if (exact) {
+            try {
+                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, name, type);
+            } catch (NoAccessException ex) {
+                mh = null;
+            }
+        } else {
             mh = retype(IDENTITY.type(), rebox(wrap, !exact));
+        }
         if (mh != null) {
             cache.put(wrap, mh);
             return mh;
@@ -474,7 +490,11 @@
                 mh = EMPTY;
                 break;
             case INT: case LONG: case FLOAT: case DOUBLE:
-                mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "zero"+wrap.simpleName(), type);
+                try {
+                    mh = IMPL_LOOKUP.findStatic(ValueConversions.class, "zero"+wrap.simpleName(), type);
+                } catch (NoAccessException ex) {
+                    mh = null;
+                }
                 break;
         }
         if (mh != null) {
@@ -549,8 +569,8 @@
             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 (RuntimeException ex) {
-            throw ex;
+        } catch (Exception ex) {
+            throw uncaughtException(ex);
         }
     }
 
--- a/src/share/classes/sun/net/InetAddressCachePolicy.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/net/InetAddressCachePolicy.java	Thu Nov 11 18:46:02 2010 -0800
@@ -25,7 +25,6 @@
 
 package sun.net;
 
-import java.net.InetAddress;
 import java.security.PrivilegedAction;
 import java.security.Security;
 
@@ -57,7 +56,7 @@
      * caching. For security reasons, this caching is made forever when
      * a security manager is set.
      */
-    private static int cachePolicy;
+    private static int cachePolicy = FOREVER;
 
     /* The Java-level namelookup cache policy for negative lookups:
      *
@@ -67,31 +66,24 @@
      * default value is 0. It can be set to some other value for
      * performance reasons.
      */
-    private static int negativeCachePolicy;
+    private static int negativeCachePolicy = NEVER;
 
     /*
      * Whether or not the cache policy for successful lookups was set
      * using a property (cmd line).
      */
-    private static boolean set = false;
+    private static boolean propertySet;
 
     /*
      * Whether or not the cache policy for negative lookups was set
      * using a property (cmd line).
      */
-    private static boolean negativeSet = false;
+    private static boolean propertyNegativeSet;
 
     /*
      * Initialize
      */
     static {
-
-        set = false;
-        negativeSet = false;
-
-        cachePolicy = FOREVER;
-        negativeCachePolicy =  0;
-
         Integer tmp = null;
 
         try {
@@ -110,7 +102,7 @@
             if (cachePolicy < 0) {
                 cachePolicy = FOREVER;
             }
-            set = true;
+            propertySet = true;
         } else {
             tmp = java.security.AccessController.doPrivileged
                 (new sun.security.action.GetIntegerAction(cachePolicyPropFallback));
@@ -119,7 +111,14 @@
                 if (cachePolicy < 0) {
                     cachePolicy = FOREVER;
                 }
-                set = true;
+                propertySet = true;
+            } else {
+                /* No properties defined for positive caching. If there is no
+                 * security manager then use the default positive cache value.
+                 */
+                if (System.getSecurityManager() == null) {
+                    cachePolicy = DEFAULT_POSITIVE;
+                }
             }
         }
 
@@ -140,7 +139,7 @@
             if (negativeCachePolicy < 0) {
                 negativeCachePolicy = FOREVER;
             }
-            negativeSet = true;
+            propertyNegativeSet = true;
         } else {
             tmp = java.security.AccessController.doPrivileged
                 (new sun.security.action.GetIntegerAction(negativeCachePolicyPropFallback));
@@ -149,17 +148,13 @@
                 if (negativeCachePolicy < 0) {
                     negativeCachePolicy = FOREVER;
                 }
-                negativeSet = true;
+                propertyNegativeSet = true;
             }
         }
     }
 
     public static synchronized int get() {
-        if (!set && System.getSecurityManager() == null) {
-            return DEFAULT_POSITIVE;
-        } else {
-            return cachePolicy;
-        }
+        return cachePolicy;
     }
 
     public static synchronized int getNegative() {
@@ -174,21 +169,17 @@
      * should be cached
      */
     public static synchronized void setIfNotSet(int newPolicy) {
-
         /*
          * When setting the new value we may want to signal that the
          * cache should be flushed, though this doesn't seem strictly
          * necessary.
          */
-
-        if (!set) {
+        if (!propertySet) {
             checkValue(newPolicy, cachePolicy);
             cachePolicy = newPolicy;
         }
-
     }
 
-
     /**
      * Sets the cache policy for negative lookups if the user has not
      * already specified a cache policy for it using a
@@ -197,14 +188,12 @@
      * should be cached
      */
     public static synchronized void setNegativeIfNotSet(int newPolicy) {
-
         /*
          * When setting the new value we may want to signal that the
          * cache should be flushed, though this doesn't seem strictly
          * necessary.
          */
-
-        if (!negativeSet) {
+        if (!propertyNegativeSet) {
             // Negative caching does not seem to have any security
             // implications.
             // checkValue(newPolicy, negativeCachePolicy);
@@ -213,13 +202,11 @@
     }
 
     private static void checkValue(int newPolicy, int oldPolicy) {
-
         /*
          * If malicious code gets a hold of this method, prevent
          * setting the cache policy to something laxer or some
          * invalid negative value.
          */
-
         if (newPolicy == FOREVER)
             return;
 
@@ -229,7 +216,6 @@
 
             throw new
                 SecurityException("can't make InetAddress cache more lax");
-
         }
     }
 }
--- a/src/share/classes/sun/net/NetworkClient.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/net/NetworkClient.java	Thu Nov 11 18:46:02 2010 -0800
@@ -40,6 +40,12 @@
  * @author      Jonathan Payne
  */
 public class NetworkClient {
+    /* Default value of read timeout, if not specified (infinity) */
+    public static final int DEFAULT_READ_TIMEOUT = -1;
+
+    /* Default value of connect timeout, if not specified (infinity) */
+    public static final int DEFAULT_CONNECT_TIMEOUT = -1;
+
     protected Proxy     proxy = Proxy.NO_PROXY;
     /** Socket for communicating with server. */
     protected Socket    serverSocket = null;
@@ -53,8 +59,8 @@
     protected static int defaultSoTimeout;
     protected static int defaultConnectTimeout;
 
-    protected int readTimeout = -1;
-    protected int connectTimeout = -1;
+    protected int readTimeout = DEFAULT_READ_TIMEOUT;
+    protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
     /* Name of encoding to use for output */
     protected static String encoding;
 
@@ -71,16 +77,12 @@
                         return null;
             }
         });
-        if (vals[0] == 0)
-            defaultSoTimeout = -1;
-        else
+        if (vals[0] != 0) {
             defaultSoTimeout = vals[0];
-
-        if (vals[1] == 0)
-            defaultConnectTimeout = -1;
-        else
+        }
+        if (vals[1] != 0) {
             defaultConnectTimeout = vals[1];
-
+        }
 
         encoding = encs[0];
         try {
@@ -232,7 +234,23 @@
         return connectTimeout;
     }
 
+    /**
+     * Sets the read timeout.
+     *
+     * Note: Public URLConnection (and protocol specific implementations)
+     * protect against negative timeout values being set. This implemenation,
+     * and protocol specific implementations, use -1 to represent the default
+     * read timeout.
+     *
+     * This method may be invoked with the default timeout value when the
+     * protocol handler is trying to reset the timeout after doing a
+     * potentially blocking internal operation, e.g. cleaning up unread
+     * response data, buffering error stream response data, etc
+     */
     public void setReadTimeout(int timeout) {
+        if (timeout == DEFAULT_READ_TIMEOUT)
+            timeout = defaultSoTimeout;
+
         if (serverSocket != null && timeout >= 0) {
             try {
                 serverSocket.setSoTimeout(timeout);
--- a/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Thu Nov 11 18:46:02 2010 -0800
@@ -46,6 +46,7 @@
 import java.util.StringTokenizer;
 import java.util.Iterator;
 import java.security.Permission;
+import sun.net.NetworkClient;
 import sun.net.www.MessageHeader;
 import sun.net.www.MeteredStream;
 import sun.net.www.URLConnection;
@@ -102,11 +103,11 @@
     static final int BIN = 2;
     static final int DIR = 3;
     int type = NONE;
-    /* Redefine timeouts from java.net.URLConnection as we nee -1 to mean
+    /* Redefine timeouts from java.net.URLConnection as we need -1 to mean
      * not set. This is to ensure backward compatibility.
      */
-    private int connectTimeout = -1;
-    private int readTimeout = -1;
+    private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT;;
+    private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT;;
 
     /**
      * For FTP URLs we need to have a special InputStream because we
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Thu Nov 11 18:46:02 2010 -0800
@@ -359,11 +359,11 @@
 
     private TunnelState tunnelState = TunnelState.NONE;
 
-    /* Redefine timeouts from java.net.URLConnection as we nee -1 to mean
+    /* Redefine timeouts from java.net.URLConnection as we need -1 to mean
      * not set. This is to ensure backward compatibility.
      */
-    private int connectTimeout = -1;
-    private int readTimeout = -1;
+    private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT;
+    private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT;
 
     /* Logging support */
     private static final PlatformLogger logger =
@@ -1041,9 +1041,9 @@
                     throw new ProtocolException("Server rejected operation");
                 }
             }
-            if (oldTimeout > 0) {
-                http.setReadTimeout(oldTimeout);
-            }
+
+            http.setReadTimeout(oldTimeout);
+
             responseCode = -1;
             responses.reset();
             // Proceed
--- a/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/net/www/protocol/https/HttpsClient.java	Thu Nov 11 18:46:02 2010 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -109,6 +109,10 @@
     // HTTPS uses a different default port number than HTTP.
     private static final int    httpsPortNumber = 443;
 
+    // default HostnameVerifier class canonical name
+    private static final String defaultHVCanonicalName =
+            "javax.net.ssl.HttpsURLConnection.DefaultHostnameVerifier";
+
     /** Returns the default HTTPS port (443) */
     @Override
     protected int getDefaultPort() { return httpsPortNumber; }
@@ -427,13 +431,93 @@
             }
             s.addHandshakeCompletedListener(this);
 
-            // if the HostnameVerifier is not set, try to enable endpoint
-            // identification during handshaking
-            boolean enabledIdentification = false;
-            if (hv instanceof DefaultHostnameVerifier &&
-                (s instanceof SSLSocketImpl) &&
-                ((SSLSocketImpl)s).trySetHostnameVerification("HTTPS")) {
-                enabledIdentification = true;
+            // We have two hostname verification approaches. One is in
+            // SSL/TLS socket layer, where the algorithm is configured with
+            // SSLParameters.setEndpointIdentificationAlgorithm(), and the
+            // hostname verification is done by X509ExtendedTrustManager when
+            // the algorithm is "HTTPS". The other one is in HTTPS layer,
+            // where the algorithm is customized by
+            // HttpsURLConnection.setHostnameVerifier(), and the hostname
+            // verification is done by HostnameVerifier when the default
+            // rules for hostname verification fail.
+            //
+            // The relationship between two hostname verification approaches
+            // likes the following:
+            //
+            //               |             EIA algorithm
+            //               +----------------------------------------------
+            //               |     null      |   HTTPS    |   LDAP/other   |
+            // -------------------------------------------------------------
+            //     |         |1              |2           |3               |
+            // HNV | default | Set HTTPS EIA | use EIA    | HTTPS          |
+            //     |--------------------------------------------------------
+            //     | non -   |4              |5           |6               |
+            //     | default | HTTPS/HNV     | use EIA    | HTTPS/HNV      |
+            // -------------------------------------------------------------
+            //
+            // Abbreviation:
+            //     EIA: the endpoint identification algorithm in SSL/TLS
+            //           socket layer
+            //     HNV: the hostname verification object in HTTPS layer
+            // Notes:
+            //     case 1. default HNV and EIA is null
+            //           Set EIA as HTTPS, hostname check done in SSL/TLS
+            //           layer.
+            //     case 2. default HNV and EIA is HTTPS
+            //           Use existing EIA, hostname check done in SSL/TLS
+            //           layer.
+            //     case 3. default HNV and EIA is other than HTTPS
+            //           Use existing EIA, EIA check done in SSL/TLS
+            //           layer, then do HTTPS check in HTTPS layer.
+            //     case 4. non-default HNV and EIA is null
+            //           No EIA, no EIA check done in SSL/TLS layer, then do
+            //           HTTPS check in HTTPS layer using HNV as override.
+            //     case 5. non-default HNV and EIA is HTTPS
+            //           Use existing EIA, hostname check done in SSL/TLS
+            //           layer. No HNV override possible. We will review this
+            //           decision and may update the architecture for JDK 7.
+            //     case 6. non-default HNV and EIA is other than HTTPS
+            //           Use existing EIA, EIA check done in SSL/TLS layer,
+            //           then do HTTPS check in HTTPS layer as override.
+            boolean needToCheckSpoofing = true;
+            String identification =
+                s.getSSLParameters().getEndpointIdentificationAlgorithm();
+            if (identification != null && identification.length() != 0) {
+                if (identification.equalsIgnoreCase("HTTPS")) {
+                    // Do not check server identity again out of SSLSocket,
+                    // the endpoint will be identified during TLS handshaking
+                    // in SSLSocket.
+                    needToCheckSpoofing = false;
+                }   // else, we don't understand the identification algorithm,
+                    // need to check URL spoofing here.
+            } else {
+                boolean isDefaultHostnameVerifier = false;
+
+                // We prefer to let the SSLSocket do the spoof checks, but if
+                // the application has specified a HostnameVerifier (HNV),
+                // we will always use that.
+                if (hv != null) {
+                    String canonicalName = hv.getClass().getCanonicalName();
+                    if (canonicalName != null &&
+                    canonicalName.equalsIgnoreCase(defaultHVCanonicalName)) {
+                        isDefaultHostnameVerifier = true;
+                    }
+                } else {
+                    // Unlikely to happen! As the behavior is the same as the
+                    // default hostname verifier, so we prefer to let the
+                    // SSLSocket do the spoof checks.
+                    isDefaultHostnameVerifier = true;
+                }
+
+                if (isDefaultHostnameVerifier) {
+                    // If the HNV is the default from HttpsURLConnection, we
+                    // will do the spoof checks in SSLSocket.
+                    SSLParameters paramaters = s.getSSLParameters();
+                    paramaters.setEndpointIdentificationAlgorithm("HTTPS");
+                    s.setSSLParameters(paramaters);
+
+                    needToCheckSpoofing = false;
+                }
             }
 
             s.startHandshake();
@@ -449,7 +533,7 @@
             }
 
             // check URL spoofing if it has not been checked under handshaking
-            if (!enabledIdentification) {
+            if (needToCheckSpoofing) {
                 checkURLSpoofing(hv);
             }
         } else {
@@ -463,8 +547,7 @@
     // Server identity checking is done according to RFC 2818: HTTP over TLS
     // Section 3.1 Server Identity
     private void checkURLSpoofing(HostnameVerifier hostnameVerifier)
-            throws IOException
-    {
+            throws IOException {
         //
         // Get authenticated server name, if any
         //
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu Nov 11 18:46:02 2010 -0800
@@ -711,10 +711,8 @@
                     cachedSenderInetAddress = isa.getAddress();
                     cachedSenderPort = isa.getPort();
 
-                    // Socket was not bound before connecting,
-                    if (localAddress == null) {
-                        localAddress = Net.localAddress(fd);
-                    }
+                    // set or refresh local address
+                    localAddress = Net.localAddress(fd);
                 }
             }
         }
@@ -735,6 +733,9 @@
                     disconnect0(fd);
                     remoteAddress = null;
                     state = ST_UNCONNECTED;
+
+                    // refresh local address
+                    localAddress = Net.localAddress(fd);
                 }
             }
         }
--- a/src/share/classes/sun/nio/ch/FileChannelImpl.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Nov 11 18:46:02 2010 -0800
@@ -699,15 +699,19 @@
         static volatile long totalSize;
         static volatile long totalCapacity;
 
-        private long address;
-        private long size;
-        private int cap;
+        private volatile long address;
+        private final long size;
+        private final int cap;
+        private final FileDescriptor fd;
 
-        private Unmapper(long address, long size, int cap) {
+        private Unmapper(long address, long size, int cap,
+                         FileDescriptor fd)
+        {
             assert (address != 0);
             this.address = address;
             this.size = size;
             this.cap = cap;
+            this.fd = fd;
 
             synchronized (Unmapper.class) {
                 count++;
@@ -722,6 +726,15 @@
             unmap0(address, size);
             address = 0;
 
+            // if this mapping has a valid file descriptor then we close it
+            if (fd.valid()) {
+                try {
+                    nd.close(fd);
+                } catch (IOException ignore) {
+                    // nothing we can do
+                }
+            }
+
             synchronized (Unmapper.class) {
                 count--;
                 totalSize -= size;
@@ -784,10 +797,12 @@
             }
             if (size == 0) {
                 addr = 0;
+                // a valid file descriptor is not required
+                FileDescriptor dummy = new FileDescriptor();
                 if ((!writable) || (imode == MAP_RO))
-                    return Util.newMappedByteBufferR(0, 0, null);
+                    return Util.newMappedByteBufferR(0, 0, dummy, null);
                 else
-                    return Util.newMappedByteBuffer(0, 0, null);
+                    return Util.newMappedByteBuffer(0, 0, dummy, null);
             }
 
             int pagePosition = (int)(position % allocationGranularity);
@@ -813,14 +828,31 @@
                 }
             }
 
+            // On Windows, and potentially other platforms, we need an open
+            // file descriptor for some mapping operations.
+            FileDescriptor mfd;
+            try {
+                mfd = nd.duplicateForMapping(fd);
+            } catch (IOException ioe) {
+                unmap0(addr, mapSize);
+                throw ioe;
+            }
+
             assert (IOStatus.checkAll(addr));
             assert (addr % allocationGranularity == 0);
             int isize = (int)size;
-            Unmapper um = new Unmapper(addr, size + pagePosition, isize);
-            if ((!writable) || (imode == MAP_RO))
-                return Util.newMappedByteBufferR(isize, addr + pagePosition, um);
-            else
-                return Util.newMappedByteBuffer(isize, addr + pagePosition, um);
+            Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
+            if ((!writable) || (imode == MAP_RO)) {
+                return Util.newMappedByteBufferR(isize,
+                                                 addr + pagePosition,
+                                                 mfd,
+                                                 um);
+            } else {
+                return Util.newMappedByteBuffer(isize,
+                                                addr + pagePosition,
+                                                mfd,
+                                                um);
+            }
         } finally {
             threads.remove(ti);
             end(IOStatus.checkAll(addr));
--- a/src/share/classes/sun/nio/ch/FileDispatcher.java	Tue Nov 02 22:15:35 2010 -0700
+++ b/src/share/classes/sun/nio/ch/FileDispatcher.java	Thu Nov 11 18:46:02 2010 -0800
@@ -45,4 +45,12 @@
 
     abstract void release(FileDescriptor fd, long pos, long size)
         throws IOException;
+
+    /**
+     * Returns a dup of fd if a file descriptor is required for
+     * memory-mapping operations, otherwise returns an invalid
+     * FileDescriptor (meaning a newly allocated FileDescriptor)
+     */
+    abstract FileDescriptor duplicateForMapping(FileDescriptor fd)
+        throws IOException;
 }
--- a/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java	Tue Nov 02 22:15:35 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,667 +0,0 @@
-/*
- * Copyright (c) 2008, 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 sun.nio.ch;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.*;
-import java.net.*;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.*;
-import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
-
-/**
- * A prototype implementation of AsynchronousDatagramChannel, used to aid
- * test and spec development.
- */
-
-class SimpleAsynchronousDatagramChannelImpl
-    extends AsynchronousDatagramChannel implements Groupable, Cancellable
-{
-    private final DatagramChannel dc;
-    private final AsynchronousChannelGroupImpl group;
-    private final Object attachKey;
-    private boolean closed;
-
-    // used to coordinate timed and blocking reads
-    private final Object readLock = new Object();
-
-    // channel blocking mode (requires readLock)
-    private boolean isBlocking = true;
-
-    // number of blocking readers (requires readLock)
-    private int blockingReaderCount;
-
-    // true if timed read attempted while blocking read in progress (requires readLock)
-    private boolean transitionToNonBlocking;
-
-    // true if a blocking read is cancelled (requires readLock)
-    private boolean blockingReadKilledByCancel;
-
-    // temporary Selectors used by timed reads (requires readLock)
-    private Selector firstReader;
-    private Set<Selector> otherReaders;
-
-    SimpleAsynchronousDatagramChannelImpl(ProtocolFamily family,
-                                          AsynchronousChannelGroupImpl group)
-        throws IOException
-    {
-        super(group.provider());
-        this.dc = (family == null) ?
-            DatagramChannel.open() : DatagramChannel.open(family);
-        this.group = group;
-
-        // attach this channel to the group as foreign channel
-        boolean registered = false;
-        try {
-            if (!(dc instanceof DatagramChannelImpl))
-                throw new UnsupportedOperationException();
-            attachKey = group
-                .attachForeignChannel(this, ((DatagramChannelImpl)dc).getFD());
-            registered = true;
-        } finally {
-            if (!registered)
-                dc.close();
-        }
-    }
-
-    // throws RuntimeException if blocking read has been cancelled
-    private void ensureBlockingReadNotKilled() {
-        assert Thread.holdsLock(readLock);
-        if (blockingReadKilledByCancel)
-            throw new RuntimeException("Reading not allowed due to cancellation");
-    }
-
-    // invoke prior to non-timed read/receive
-    private void beginNoTimeoutRead() {
-        synchronized (readLock) {
-            ensureBlockingReadNotKilled();
-            if (isBlocking)
-                blockingReaderCount++;
-        }
-    }
-
-    // invoke after non-timed read/receive has completed
-    private void endNoTimeoutRead() {
-        synchronized (readLock) {
-            if (isBlocking) {
-                if (--blockingReaderCount == 0 && transitionToNonBlocking) {
-                    // notify any threads waiting to make channel non-blocking
-                    readLock.notifyAll();
-                }
-            }
-        }
-    }
-
-    // invoke prior to timed read
-    // returns the timeout remaining
-    private long prepareForTimedRead(PendingFuture<?,?> result, long timeout)
-        throws IOException
-    {
-        synchronized (readLock) {
-            ensureBlockingReadNotKilled();
-            if (isBlocking) {
-                transitionToNonBlocking = true;
-                while (blockingReaderCount > 0 &&
-                       timeout > 0L &&
-                       !result.isCancelled())
-                {
-                    long st = System.currentTimeMillis();
-                    try {
-                        readLock.wait(timeout);
-                    } catch (InterruptedException e) { }
-                    timeout -= System.currentTimeMillis() - st;
-                }
-                if (blockingReaderCount == 0) {
-                    // re-check that blocked read wasn't cancelled
-                    ensureBlockingReadNotKilled();
-                    // no blocking reads so change channel to non-blocking
-                    dc.configureBlocking(false);
-                    isBlocking = false;
-                }
-            }
-            return timeout;
-        }
-    }
-
-    // returns a temporary Selector
-    private Selector getSelector() throws IOException {
-        Selector sel = Util.getTemporarySelector(dc);
-        synchronized (readLock) {
-            if (firstReader == null) {
-                firstReader = sel;
-            } else {
-                if (otherReaders == null)
-                    otherReaders = new HashSet<Selector>();
-                otherReaders.add(sel);
-            }
-        }
-        return sel;
-    }
-
-    // releases a temporary Selector
-    private void releaseSelector(Selector sel) throws IOException {
-        synchronized (readLock) {
-            if (firstReader == sel) {
-                firstReader = null;
-            } else {
-                otherReaders.remove(sel);
-            }
-        }
-        Util.releaseTemporarySelector(sel);
-    }
-
-    // wakeup all Selectors currently in use
-    private void wakeupSelectors() {
-        synchronized (readLock) {
-            if (firstReader != null)
-                firstReader.wakeup();
-            if (otherReaders != null) {
-                for (Selector sel: otherReaders) {
-                    sel.wakeup();
-                }
-            }
-        }
-    }
-
-    @Override
-    public AsynchronousChannelGroupImpl group() {
-        return group;
-    }
-
-    @Override
-    public boolean isOpen() {
-        return dc.isOpen();
-    }
-
-    @Override
-    public void onCancel(PendingFuture<?,?> task) {
-        synchronized (readLock) {
-            if (blockingReaderCount > 0) {
-                blockingReadKilledByCancel = true;
-                readLock.notifyAll();
-                return;
-            }
-        }
-        wakeupSelectors();
-    }
-
-    @Override
-    public void close() throws IOException {
-        synchronized (dc) {
-            if (closed)
-                return;
-            closed = true;
-        }
-        // detach from group and close underlying channel
-        group.detachForeignChannel(attachKey);
-        dc.close();
-
-        // wakeup any threads blocked in timed read/receives
-        wakeupSelectors();
-    }
-
-    @Override
-    public AsynchronousDatagramChannel connect(SocketAddress remote)
-        throws IOException
-    {
-        dc.connect(remote);
-        return this;
-    }
-
-    @Override
-    public AsynchronousDatagramChannel disconnect() throws IOException {
-        dc.disconnect();
-        return this;
-    }
-
-    private static class WrappedMembershipKey extends MembershipKey {
-        private final MulticastChannel channel;
-        private final MembershipKey key;
-
-        WrappedMembershipKey(MulticastChannel channel, MembershipKey key) {
-            this.channel = channel;
-            this.key = key;
-        }
-
-        @Override
-        public boolean isValid() {
-            return key.isValid();
-        }
-
-        @Override
-        public void drop() {
-            key.drop();
-        }
-
-        @Override
-        public MulticastChannel channel() {
-            return channel;
-        }
-
-        @Override
-        public InetAddress group() {
-            return key.group();
-        }
-
-        @Override
-        public NetworkInterface networkInterface() {
-            return key.networkInterface();
-        }
-
-        @Override
-        public InetAddress sourceAddress() {
-            return key.sourceAddress();
-        }
-
-        @Override
-        public MembershipKey block(InetAddress toBlock) throws IOException {
-            key.block(toBlock);
-            return this;
-        }
-
-        @Override
-        public MembershipKey unblock(InetAddress toUnblock) {
-            key.unblock(toUnblock);
-            return this;
-        }
-
-        @Override
-        public String toString() {
-            return key.toString();
-        }
-    }
-
-    @Override
-    public MembershipKey join(InetAddress group,
-                              NetworkInterface interf)
-        throws IOException
-    {
-        MembershipKey key = ((MulticastChannel)dc).join(group, interf);
-        return new WrappedMembershipKey(this, key);
-    }
-
-    @Override
-    public MembershipKey join(InetAddress group,
-                              NetworkInterface interf,
-                              InetAddress source)
-        throws IOException
-    {
-        MembershipKey key = ((MulticastChannel)dc).join(group, interf, source);
-        return new WrappedMembershipKey(this, key);
-    }
-
-    private <A> Future<Integer> implSend(ByteBuffer src,
-                                         SocketAddress target,
-                                         A attachment,
-                                         CompletionHandler<Integer,? super A> handler)
-    {
-        int n = 0;
-        Throwable exc = null;
-        try {
-            n = dc.send(src, target);
-        } catch (IOException ioe) {
-            exc = ioe;
-        }
-        if (handler == null)
-            return CompletedFuture.withResult(n, exc);
-        Invoker.invoke(this, handler, attachment, n, exc);
-        return null;
-    }
-
-    @Override
-    public Future<Integer> send(ByteBuffer src, SocketAddress target) {
-        return implSend(src, target, null, null);
-    }
-
-    @Override
-    public <A> void send(ByteBuffer src,
-                         SocketAddress target,
-                         A attachment,
-                         CompletionHandler<Integer,? super A> handler)
-    {
-        if (handler == null)
-            throw new NullPointerException("'handler' is null");
-        implSend(src, target, attachment, handler);
-    }
-
-    private <A> Future<Integer> implWrite(ByteBuffer src,
-                                          A attachment,
-                                          CompletionHandler<Integer,? super A> handler)
-    {
-        int n = 0;
-        Throwable exc = null;
-        try {
-            n = dc.write(src);
-        } catch (IOException ioe) {
-            exc = ioe;
-        }
-        if (handler == null)
-            return CompletedFuture.withResult(n, exc);
-        Invoker.invoke(this, handler, attachment, n, exc);
-        return null;
-
-    }
-
-    @Override
-    public Future<Integer> write(ByteBuffer src) {
-        return implWrite(src, null, null);
-    }
-
-    @Override
-    public <A> void write(ByteBuffer src,
-                          A attachment,
-                          CompletionHandler<Integer,? super A> handler)
-    {
-        if (handler == null)
-            throw new NullPointerException("'handler' is null");
-        implWrite(src, attachment, handler);
-    }
-
-    /**
-     * Receive into the given buffer with privileges enabled and restricted by
-     * the given AccessControlContext (can be null).
-     */
-    private SocketAddress doRestrictedReceive(final ByteBuffer dst,
-                                              AccessControlContext acc)
-        throws IOException
-    {
-        if (acc == null) {
-            return dc.receive(dst);
-        } else {
-            try {
-                return AccessController.doPrivileged(
-                    new PrivilegedExceptionAction<SocketAddress>() {
-                        public SocketAddress run() throws IOException {
-                            return dc.receive(dst);
-                        }}, acc);
-            } catch (PrivilegedActionException pae) {
-                Exception cause = pae.getException();
-                if (cause instanceof SecurityException)
-                    throw (SecurityException)cause;
-                throw (IOException)cause;
-            }
-        }
-    }
-
-    private <A> Future<SocketAddress> implReceive(final ByteBuffer dst,
-                                                  final long timeout,
-                                                  final TimeUnit unit,
-                                                  A attachment,
-                                                  final CompletionHandler<SocketAddress,? super A> handler)
-    {
-        if (dst.isReadOnly())
-            throw new IllegalArgumentException("Read-only buffer");
-        if (timeout < 0L)
-            throw new IllegalArgumentException("Negative timeout");
-        if (unit == null)
-            throw new NullPointerException();
-
-        // complete immediately if channel closed
-        if (!isOpen()) {
-            Throwable exc = new ClosedChannelException();
-            if (handler == null)
-                return CompletedFuture.withFailure(exc);
-            Invoker.invoke(this, handler, attachment, null, exc);
-            return null;
-        }
-
-        final AccessControlContext acc = (System.getSecurityManager() == null) ?
-            null : AccessController.getContext();
-        final PendingFuture<SocketAddress,A> result =
-            new PendingFuture<SocketAddress,A>(this, handler, attachment);
-        Runnable task = new Runnable() {
-            public void run() {
-                try {
-                    SocketAddress remote = null;
-                    long to;
-                    if (timeout == 0L) {
-                        beginNoTimeoutRead();
-                        try {
-                            remote = doRestrictedReceive(dst, acc);
-                        } finally {
-                            endNoTimeoutRead();
-                        }
-                        to = 0L;
-                    } else {
-                        to = prepareForTimedRead(result, unit.toMillis(timeout));
-                        if (to <= 0L)
-                            throw new InterruptedByTimeoutException();
-                        remote = doRestrictedReceive(dst, acc);
-                    }
-                    if (remote == null) {
-                        Selector sel = getSelector();
-                        SelectionKey sk = null;
-                        try {
-                            sk = dc.register(sel, SelectionKey.OP_READ);
-                            for (;;) {
-                                if (!dc.isOpen())
-                                    throw new AsynchronousCloseException();
-                                if (result.isCancelled())
-                                    break;
-                                long st = System.currentTimeMillis();
-                                int ns = sel.select(to);
-                                if (ns > 0) {
-                                    remote = doRestrictedReceive(dst, acc);
-                                    if (remote != null)
-                                        break;
-                                }
-                                sel.selectedKeys().remove(sk);
-                                if (timeout != 0L) {
-                                    to -= System.currentTimeMillis() - st;
-                                    if (to <= 0)
-                                        throw new InterruptedByTimeoutException();
-                                }
-                            }
-                        } finally {
-                            if (sk != null)
-                                sk.cancel();
-                            releaseSelector(sel);
-                        }
-                    }
-                    result.setResult(remote);
-                } catch (Throwable x) {
-                    if (x instanceof ClosedChannelException)
-                        x = new AsynchronousCloseException();
-                    result.setFailure(x);
-                }
-                Invoker.invokeUnchecked(result);
-            }
-        };
-        try {
-            group.executeOnPooledThread(task);
-        } catch (RejectedExecutionException ree) {
-            throw new ShutdownChannelGroupException();
-        }
-        return result;
-    }
-
-    @Override
-    public Future<SocketAddress> receive(ByteBuffer dst) {
-        return implReceive(dst, 0L, TimeUnit.MILLISECONDS, null, null);
-    }
-
-    @Override