Merge
authorlana
Wed, 16 Jan 2013 11:58:15 -0800
changeset 15171 15b8cd02927b
parent 15170 dc5d3102a97f (current diff)
parent 15047 fe94b40ffd93 (diff)
child 15172 ddb13fe8f537
Merge
--- a/.hgtags	Thu Jan 10 19:36:13 2013 -0800
+++ b/.hgtags	Wed Jan 16 11:58:15 2013 -0800
@@ -192,3 +192,5 @@
 cb33628d4e8f11e879c371959e5948b66a53376f jdk8-b68
 adb5171c554e14cd86f618b5584f6e3d693d5889 jdk8-b69
 0d625373c69e2ad6f546fd88ab50c6c9aad01271 jdk8-b70
+a41ada2ed4ef735449531c6ebe6cec593d890a1c jdk8-b71
+6725b3961f987cf40f446d1c11cd324a3bec545f jdk8-b72
--- a/.hgtags-top-repo	Thu Jan 10 19:36:13 2013 -0800
+++ b/.hgtags-top-repo	Wed Jan 16 11:58:15 2013 -0800
@@ -192,3 +192,5 @@
 cdb401a60cea6ad5ef3f498725ed1decf8dda1ea jdk8-b68
 6ee8080a6efe0639fcd00627a5e0f839bf010481 jdk8-b69
 105a25ffa4a4f0af70188d4371b4a0385009b7ce jdk8-b70
+51ad2a34342055333eb5f36e2fb514b027895708 jdk8-b71
+c1be681d80a1f1c848dc671d664fccb19e046a12 jdk8-b72
--- a/corba/.hgtags	Thu Jan 10 19:36:13 2013 -0800
+++ b/corba/.hgtags	Wed Jan 16 11:58:15 2013 -0800
@@ -192,3 +192,5 @@
 82000531feaa7baef76b6406099e5cd88943d635 jdk8-b68
 22ddcac208a8dea894a16887d04f3ca4d3c5d267 jdk8-b69
 603cceb495c8133d47b26a7502d51c7d8a67d76b jdk8-b70
+8171d23e914d758836527b80b06debcfdb718f2d jdk8-b71
+cb40427f47145b01b7e53c3e02b38ff7625efbda jdk8-b72
--- a/hotspot/.hgtags	Thu Jan 10 19:36:13 2013 -0800
+++ b/hotspot/.hgtags	Wed Jan 16 11:58:15 2013 -0800
@@ -304,3 +304,5 @@
 cb8a4e04bc8c104de8a2f67463c7e31232bf8d68 jdk8-b69
 990bbd393c239d95310ccc38094e57923bbf1d4a hs25-b14
 e94068d4ff52849c8aa0786a53a59b63d1312a39 jdk8-b70
+0847210f85480bf3848dc90bc2ab23c0a4791b55 jdk8-b71
+d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72
--- a/jaxp/.hgtags	Thu Jan 10 19:36:13 2013 -0800
+++ b/jaxp/.hgtags	Wed Jan 16 11:58:15 2013 -0800
@@ -192,3 +192,5 @@
 b854e70084214e9dcf1b37373f6e4b1a68760e03 jdk8-b68
 789a855de959f7e9600e57759c6c3dbb0b24d78b jdk8-b69
 6ec9edffc286c9c9ac96c9cd2050b01cb5d514a8 jdk8-b70
+499be952a291cec1dc774a84a238941d6faf772d jdk8-b71
+bdf2af722a6b54fca47d8c51d17a1b8f41dd7a3e jdk8-b72
--- a/jaxws/.hgtags	Thu Jan 10 19:36:13 2013 -0800
+++ b/jaxws/.hgtags	Wed Jan 16 11:58:15 2013 -0800
@@ -192,3 +192,5 @@
 d3fe408f3a9ad250bc9a4e9365bdfc3f28c1d3f4 jdk8-b68
 756323c990115a9c0341d67b10f2d52c6370e35d jdk8-b69
 3b1c2733d47ee9f8c530925df4041c59f9ee5a31 jdk8-b70
+f577a39c9fb3d5820248c13c2cc74a192a9313e0 jdk8-b71
+d9707230294d54e695e745a90de6112909100f12 jdk8-b72
--- a/jdk/.hgtags	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/.hgtags	Wed Jan 16 11:58:15 2013 -0800
@@ -192,3 +192,5 @@
 53fb43e4d614c92310e1fb00ec41d1960fd9facf jdk8-b68
 a8012d8d7e9c5035de0bdd4887dc9f7c54008f21 jdk8-b69
 a996b57e554198f4592a5f3c30f2f9f4075e545d jdk8-b70
+2a5af0f766d0acd68a81fb08fe11fd66795f86af jdk8-b71
+32a57e645e012a1f0665c075969ca598e0dbb948 jdk8-b72
--- a/jdk/make/common/Release.gmk	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/make/common/Release.gmk	Wed Jan 16 11:58:15 2013 -0800
@@ -375,6 +375,7 @@
 	com/sun/tools/javadoc   \
 	com/sun/tools/javah     \
 	com/sun/tools/javap     \
+	com/sun/tools/jdeps     \
 	com/sun/tools/corba     \
 	com/sun/tools/internal/xjc       \
 	com/sun/tools/internal/ws       \
@@ -457,6 +458,7 @@
 	javadoc$(EXE_SUFFIX) \
 	javah$(EXE_SUFFIX) \
 	javap$(EXE_SUFFIX) \
+	jdeps$(EXE_SUFFIX) \
 	jcmd$(EXE_SUFFIX) \
 	jdb$(EXE_SUFFIX) \
 	jps$(EXE_SUFFIX) \
@@ -564,6 +566,7 @@
 	$(ECHO) "sun/tools/javac/" >> $@
 	$(ECHO) "com/sun/tools/classfile/" >> $@
 	$(ECHO) "com/sun/tools/javap/" >> $@
+	$(ECHO) "com/sun/tools/jdeps/" >> $@
 	$(ECHO) "sun/tools/jcmd/" >> $@
 	$(ECHO) "sun/tools/jconsole/" >> $@
 	$(ECHO) "sun/tools/jps/" >> $@
--- a/jdk/make/docs/NON_CORE_PKGS.gmk	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/make/docs/NON_CORE_PKGS.gmk	Wed Jan 16 11:58:15 2013 -0800
@@ -76,7 +76,7 @@
 
 JCONSOLE_PKGS    = com.sun.tools.jconsole
 
-TREEAPI_PKGS 	 = com.sunsource.doctree \
+TREEAPI_PKGS 	 = com.sun.source.doctree \
 		   com.sun.source.tree \
 		   com.sun.source.util
 
--- a/jdk/make/launchers/Makefile	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/make/launchers/Makefile	Wed Jan 16 11:58:15 2013 -0800
@@ -63,6 +63,7 @@
 $(call make-launcher, javadoc, com.sun.tools.javadoc.Main, , )
 $(call make-launcher, javah, com.sun.tools.javah.Main, , )
 $(call make-launcher, javap, com.sun.tools.javap.Main, , )
+$(call make-launcher, jdeps, com.sun.tools.jdeps.Main, , )
 $(call make-launcher, jcmd, sun.tools.jcmd.JCmd, , )
 $(call make-launcher, jconsole, sun.tools.jconsole.JConsole, \
   -J-Djconsole.showOutputViewer, )
--- a/jdk/make/launchers/Makefile.launcher	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/make/launchers/Makefile.launcher	Wed Jan 16 11:58:15 2013 -0800
@@ -62,6 +62,10 @@
   WILDCARDS=true
   NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
 endif
+ifeq ($(PROGRAM),jdeps)
+  WILDCARDS=true
+  NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
+endif
 ifeq ($(PROGRAM),javah)
   WILDCARDS=true
   NEVER_ACT_AS_SERVER_CLASS_MACHINE=true
--- a/jdk/makefiles/CompileLaunchers.gmk	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/makefiles/CompileLaunchers.gmk	Wed Jan 16 11:58:15 2013 -0800
@@ -267,6 +267,11 @@
     -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
     -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.javap.Main"$(COMMA) }'))
 
+$(eval $(call SetupLauncher,jdeps,\
+    -DEXPAND_CLASSPATH_WILDCARDS \
+    -DNEVER_ACT_AS_SERVER_CLASS_MACHINE \
+    -DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.jdeps.Main"$(COMMA) }'))
+
 BUILD_LAUNCHER_jconsole_CFLAGS_windows:=-DJAVAW
 BUILD_LAUNCHER_jconsole_LDFLAGS_windows:=user32.lib
 
--- a/jdk/makefiles/CreateJars.gmk	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/makefiles/CreateJars.gmk	Wed Jan 16 11:58:15 2013 -0800
@@ -738,6 +738,7 @@
 	com/sun/tools/javadoc   \
 	com/sun/tools/javah     \
 	com/sun/tools/javap     \
+	com/sun/tools/jdeps	\
 	com/sun/tools/corba     \
 	com/sun/tools/internal/xjc       \
 	com/sun/tools/internal/ws       \
--- a/jdk/makefiles/Images.gmk	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/makefiles/Images.gmk	Wed Jan 16 11:58:15 2013 -0800
@@ -100,6 +100,7 @@
 	javadoc$(EXE_SUFFIX) \
 	javah$(EXE_SUFFIX) \
 	javap$(EXE_SUFFIX) \
+	jdeps$(EXE_SUFFIX) \
 	jcmd$(EXE_SUFFIX) \
 	jdb$(EXE_SUFFIX) \
 	jps$(EXE_SUFFIX) \
--- a/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/AESCipher.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 import javax.crypto.*;
 import javax.crypto.spec.*;
 import javax.crypto.BadPaddingException;
+import java.nio.ByteBuffer;
 
 /**
  * This class implements the AES algorithm in its various modes
@@ -127,6 +128,21 @@
             super(32, "CFB", "NOPADDING");
         }
     }
+    public static final class AES128_GCM_NoPadding extends OidImpl {
+        public AES128_GCM_NoPadding() {
+            super(16, "GCM", "NOPADDING");
+        }
+    }
+    public static final class AES192_GCM_NoPadding extends OidImpl {
+        public AES192_GCM_NoPadding() {
+            super(24, "GCM", "NOPADDING");
+        }
+    }
+    public static final class AES256_GCM_NoPadding extends OidImpl {
+        public AES256_GCM_NoPadding() {
+            super(32, "GCM", "NOPADDING");
+        }
+    }
 
     // utility method used by AESCipher and AESWrapCipher
     static final void checkKeySize(Key key, int fixedKeySize)
@@ -531,4 +547,79 @@
         return core.unwrap(wrappedKey, wrappedKeyAlgorithm,
                            wrappedKeyType);
     }
+
+    /**
+     * Continues a multi-part update of the Additional Authentication
+     * Data (AAD), using a subset of the provided buffer.
+     * <p>
+     * Calls to this method provide AAD to the cipher when operating in
+     * modes such as AEAD (GCM/CCM).  If this cipher is operating in
+     * either GCM or CCM mode, all AAD must be supplied before beginning
+     * operations on the ciphertext (via the {@code update} and {@code
+     * doFinal} methods).
+     *
+     * @param src the buffer containing the AAD
+     * @param offset the offset in {@code src} where the AAD input starts
+     * @param len the number of AAD bytes
+     *
+     * @throws IllegalStateException if this cipher is in a wrong state
+     * (e.g., has not been initialized), does not accept AAD, or if
+     * operating in either GCM or CCM mode and one of the {@code update}
+     * methods has already been called for the active
+     * encryption/decryption operation
+     * @throws UnsupportedOperationException if this method
+     * has not been overridden by an implementation
+     *
+     * @since 1.8
+     */
+    @Override
+    protected void engineUpdateAAD(byte[] src, int offset, int len) {
+        core.updateAAD(src, offset, len);
+    }
+
+    /**
+     * Continues a multi-part update of the Additional Authentication
+     * Data (AAD).
+     * <p>
+     * Calls to this method provide AAD to the cipher when operating in
+     * modes such as AEAD (GCM/CCM).  If this cipher is operating in
+     * either GCM or CCM mode, all AAD must be supplied before beginning
+     * operations on the ciphertext (via the {@code update} and {@code
+     * doFinal} methods).
+     * <p>
+     * All {@code src.remaining()} bytes starting at
+     * {@code src.position()} are processed.
+     * Upon return, the input buffer's position will be equal
+     * to its limit; its limit will not have changed.
+     *
+     * @param src the buffer containing the AAD
+     *
+     * @throws IllegalStateException if this cipher is in a wrong state
+     * (e.g., has not been initialized), does not accept AAD, or if
+     * operating in either GCM or CCM mode and one of the {@code update}
+     * methods has already been called for the active
+     * encryption/decryption operation
+     * @throws UnsupportedOperationException if this method
+     * has not been overridden by an implementation
+     *
+     * @since 1.8
+     */
+    @Override
+    protected void engineUpdateAAD(ByteBuffer src) {
+        if (src != null) {
+            int aadLen = src.limit() - src.position();
+            if (aadLen != 0) {
+                if (src.hasArray()) {
+                    int aadOfs = src.arrayOffset() + src.position();
+                    core.updateAAD(src.array(), aadOfs, aadLen);
+                    src.position(src.limit());
+                } else {
+                    byte[] aad = new byte[aadLen];
+                    src.get(aad);
+                    core.updateAAD(aad, 0, aadLen);
+                }
+            }
+        }
+    }
 }
+
--- a/jdk/src/share/classes/com/sun/crypto/provider/AESKeyGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/AESKeyGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -106,7 +106,7 @@
         SecretKeySpec aesKey = null;
 
         if (this.random == null) {
-            this.random = SunJCE.RANDOM;
+            this.random = SunJCE.getRandom();
         }
 
         byte[] keyBytes = new byte[keySize];
--- a/jdk/src/share/classes/com/sun/crypto/provider/BlowfishKeyGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/BlowfishKeyGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,7 +104,7 @@
      */
     protected SecretKey engineGenerateKey() {
         if (this.random == null) {
-            this.random = SunJCE.RANDOM;
+            this.random = SunJCE.getRandom();
         }
 
         byte[] keyBytes = new byte[this.keysize];
--- a/jdk/src/share/classes/com/sun/crypto/provider/CipherCore.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/CipherCore.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 
 package com.sun.crypto.provider;
 
+import java.util.Arrays;
 import java.util.Locale;
 
 import java.security.*;
@@ -59,7 +60,7 @@
     private byte[] buffer = null;
 
     /*
-     * internal buffer
+     * block size of cipher in bytes
      */
     private int blockSize = 0;
 
@@ -76,10 +77,12 @@
     /*
      * minimum number of bytes in the buffer required for
      * FeedbackCipher.encryptFinal()/decryptFinal() call.
-     * update() must buffer this many bytes before before starting
+     * update() must buffer this many bytes before starting
      * to encrypt/decrypt data.
-     * currently, only CTS mode has a non-zero value due to its special
-     * handling on the last two blocks (the last one may be incomplete).
+     * currently, only the following cases have non-zero values:
+     * 1) CTS mode - due to its special handling on the last two blocks
+     * (the last one may be incomplete).
+     * 2) GCM mode + decryption - due to its trailing tag bytes
      */
     private int minBytes = 0;
 
@@ -121,6 +124,24 @@
     private static final int PCBC_MODE = 4;
     private static final int CTR_MODE = 5;
     private static final int CTS_MODE = 6;
+    private static final int GCM_MODE = 7;
+
+    /*
+     * variables used for performing the GCM (key+iv) uniqueness check.
+     * To use GCM mode safely, the cipher object must be re-initialized
+     * with a different combination of key + iv values for each
+     * encryption operation. However, checking all past key + iv values
+     * isn't feasible. Thus, we only do a per-instance check of the
+     * key + iv values used in previous encryption.
+     * For decryption operations, no checking is necessary.
+     * NOTE: this key+iv check have to be done inside CipherCore class
+     * since CipherCore class buffers potential tag bytes in GCM mode
+     * and may not call GaloisCounterMode when there isn't sufficient
+     * input to process.
+     */
+    private boolean requireReinit = false;
+    private byte[] lastEncKey = null;
+    private byte[] lastEncIv = null;
 
     /**
      * Creates an instance of CipherCore with default ECB mode and
@@ -149,7 +170,7 @@
      * @param mode the cipher mode
      *
      * @exception NoSuchAlgorithmException if the requested cipher mode does
-     * not exist
+     * not exist for this cipher
      */
     void setMode(String mode) throws NoSuchAlgorithmException {
         if (mode == null)
@@ -165,30 +186,34 @@
         if (modeUpperCase.equals("CBC")) {
             cipherMode = CBC_MODE;
             cipher = new CipherBlockChaining(rawImpl);
-        }
-        else if (modeUpperCase.equals("CTS")) {
+        } else if (modeUpperCase.equals("CTS")) {
             cipherMode = CTS_MODE;
             cipher = new CipherTextStealing(rawImpl);
             minBytes = blockSize+1;
             padding = null;
-        }
-        else if (modeUpperCase.equals("CTR")) {
+        } else if (modeUpperCase.equals("CTR")) {
             cipherMode = CTR_MODE;
             cipher = new CounterMode(rawImpl);
             unitBytes = 1;
             padding = null;
-        }
-        else if (modeUpperCase.startsWith("CFB")) {
+        }  else if (modeUpperCase.startsWith("GCM")) {
+            // can only be used for block ciphers w/ 128-bit block size
+            if (blockSize != 16) {
+                throw new NoSuchAlgorithmException
+                    ("GCM mode can only be used for AES cipher");
+            }
+            cipherMode = GCM_MODE;
+            cipher = new GaloisCounterMode(rawImpl);
+            padding = null;
+        } else if (modeUpperCase.startsWith("CFB")) {
             cipherMode = CFB_MODE;
             unitBytes = getNumOfUnit(mode, "CFB".length(), blockSize);
             cipher = new CipherFeedback(rawImpl, unitBytes);
-        }
-        else if (modeUpperCase.startsWith("OFB")) {
+        } else if (modeUpperCase.startsWith("OFB")) {
             cipherMode = OFB_MODE;
             unitBytes = getNumOfUnit(mode, "OFB".length(), blockSize);
             cipher = new OutputFeedback(rawImpl, unitBytes);
-        }
-        else if (modeUpperCase.equals("PCBC")) {
+        } else if (modeUpperCase.equals("PCBC")) {
             cipherMode = PCBC_MODE;
             cipher = new PCBC(rawImpl);
         }
@@ -219,6 +244,7 @@
         return result;
     }
 
+
     /**
      * Sets the padding mechanism of this cipher.
      *
@@ -242,11 +268,27 @@
                                              + " not implemented");
         }
         if ((padding != null) &&
-            ((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE))) {
+            ((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE)
+             || (cipherMode == GCM_MODE))) {
             padding = null;
-            throw new NoSuchPaddingException
-                ((cipherMode == CTR_MODE? "CTR":"CTS") +
-                 " mode must be used with NoPadding");
+            String modeStr = null;
+            switch (cipherMode) {
+            case CTR_MODE:
+                modeStr = "CTR";
+                break;
+            case GCM_MODE:
+                modeStr = "GCM";
+                break;
+            case CTS_MODE:
+                modeStr = "CTS";
+                break;
+            default:
+                // should never happen
+            }
+            if (modeStr != null) {
+                throw new NoSuchPaddingException
+                    (modeStr + " mode must be used with NoPadding");
+            }
         }
     }
 
@@ -257,7 +299,7 @@
      * <code>inputLen</code> (in bytes).
      *
      * <p>This call takes into account any unprocessed (buffered) data from a
-     * previous <code>update</code> call, and padding.
+     * previous <code>update</code> call, padding, and AEAD tagging.
      *
      * <p>The actual output length of the next <code>update</code> or
      * <code>doFinal</code> call may be smaller than the length returned by
@@ -270,23 +312,60 @@
     int getOutputSize(int inputLen) {
         int totalLen = buffered + inputLen;
 
-        if (padding == null)
-            return totalLen;
+        // GCM: this call may be for either update() or doFinal(), so have to
+        // return the larger value of both
+        // Encryption: based on doFinal value: inputLen + tag
+        // Decryption: based on update value: inputLen
+        if (!decrypting && (cipherMode == GCM_MODE)) {
+            return (totalLen + ((GaloisCounterMode) cipher).getTagLen());
+        }
 
-        if (decrypting)
+        if (padding == null) {
             return totalLen;
+        }
+
+        if (decrypting) {
+            return totalLen;
+        }
 
         if (unitBytes != blockSize) {
-            if (totalLen < diffBlocksize)
+            if (totalLen < diffBlocksize) {
                 return diffBlocksize;
-            else
+            } else {
                 return (totalLen + blockSize -
                         ((totalLen - diffBlocksize) % blockSize));
+            }
         } else {
             return totalLen + padding.padLength(totalLen);
         }
     }
 
+    private int getOutputSizeByOperation(int inputLen, boolean isDoFinal) {
+        int totalLen = 0;
+        switch (cipherMode) {
+        case GCM_MODE:
+            totalLen = buffered + inputLen;
+            if (isDoFinal) {
+                int tagLen = ((GaloisCounterMode) cipher).getTagLen();
+                if (decrypting) {
+                    // need to get the actual value from cipher??
+                    // deduct tagLen
+                    totalLen -= tagLen;
+                } else {
+                    totalLen += tagLen;
+                }
+            }
+            if (totalLen < 0) {
+                totalLen = 0;
+            }
+            break;
+        default:
+             totalLen  = getOutputSize(inputLen);
+             break;
+        }
+        return totalLen;
+    }
+
     /**
      * Returns the initialization vector (IV) in a new buffer.
      *
@@ -318,34 +397,49 @@
      * does not use any parameters.
      */
     AlgorithmParameters getParameters(String algName) {
+        if (cipherMode == ECB_MODE) {
+            return null;
+        }
         AlgorithmParameters params = null;
-        if (cipherMode == ECB_MODE) return null;
+        AlgorithmParameterSpec spec;
         byte[] iv = getIV();
-        if (iv != null) {
-            AlgorithmParameterSpec ivSpec;
-            if (algName.equals("RC2")) {
-                RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher();
-                ivSpec = new RC2ParameterSpec(rawImpl.getEffectiveKeyBits(),
-                                              iv);
+        if (iv == null) {
+            // generate spec using default value
+            if (cipherMode == GCM_MODE) {
+                iv = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
             } else {
-                ivSpec = new IvParameterSpec(iv);
+                iv = new byte[blockSize];
             }
-            try {
-                params = AlgorithmParameters.getInstance(algName, "SunJCE");
-            } catch (NoSuchAlgorithmException nsae) {
-                // should never happen
-                throw new RuntimeException("Cannot find " + algName +
-                    " AlgorithmParameters implementation in SunJCE provider");
-            } catch (NoSuchProviderException nspe) {
-                // should never happen
-                throw new RuntimeException("Cannot find SunJCE provider");
-            }
-            try {
-                params.init(ivSpec);
-            } catch (InvalidParameterSpecException ipse) {
-                // should never happen
-                throw new RuntimeException("IvParameterSpec not supported");
-            }
+            SunJCE.getRandom().nextBytes(iv);
+        }
+        if (cipherMode == GCM_MODE) {
+            algName = "GCM";
+            spec = new GCMParameterSpec
+                (((GaloisCounterMode) cipher).getTagLen()*8, iv);
+        } else {
+           if (algName.equals("RC2")) {
+               RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher();
+               spec = new RC2ParameterSpec
+                   (rawImpl.getEffectiveKeyBits(), iv);
+           } else {
+               spec = new IvParameterSpec(iv);
+           }
+        }
+        try {
+            params = AlgorithmParameters.getInstance(algName, "SunJCE");
+        } catch (NoSuchAlgorithmException nsae) {
+            // should never happen
+            throw new RuntimeException("Cannot find " + algName +
+                " AlgorithmParameters implementation in SunJCE provider");
+        } catch (NoSuchProviderException nspe) {
+            // should never happen
+            throw new RuntimeException("Cannot find SunJCE provider");
+        }
+        try {
+            params.init(spec);
+        } catch (InvalidParameterSpecException ipse) {
+            // should never happen
+            throw new RuntimeException(spec.getClass() + " not supported");
         }
         return params;
     }
@@ -420,44 +514,63 @@
                   || (opmode == Cipher.UNWRAP_MODE);
 
         byte[] keyBytes = getKeyBytes(key);
-
-        byte[] ivBytes;
-        if (params == null) {
-            ivBytes = null;
-        } else if (params instanceof IvParameterSpec) {
-            ivBytes = ((IvParameterSpec)params).getIV();
-            if ((ivBytes == null) || (ivBytes.length != blockSize)) {
-                throw new InvalidAlgorithmParameterException
-                    ("Wrong IV length: must be " + blockSize +
-                    " bytes long");
+        int tagLen = -1;
+        byte[] ivBytes = null;
+        if (params != null) {
+            if (cipherMode == GCM_MODE) {
+                if (params instanceof GCMParameterSpec) {
+                    tagLen = ((GCMParameterSpec)params).getTLen();
+                    if (tagLen < 96 || tagLen > 128 || ((tagLen & 0x07) != 0)) {
+                        throw new InvalidAlgorithmParameterException
+                            ("Unsupported TLen value; must be one of " +
+                             "{128, 120, 112, 104, 96}");
+                    }
+                    tagLen = tagLen >> 3;
+                    ivBytes = ((GCMParameterSpec)params).getIV();
+                } else {
+                    throw new InvalidAlgorithmParameterException
+                        ("Unsupported parameter: " + params);
+               }
+            } else {
+                if (params instanceof IvParameterSpec) {
+                    ivBytes = ((IvParameterSpec)params).getIV();
+                    if ((ivBytes == null) || (ivBytes.length != blockSize)) {
+                        throw new InvalidAlgorithmParameterException
+                            ("Wrong IV length: must be " + blockSize +
+                             " bytes long");
+                    }
+                } else if (params instanceof RC2ParameterSpec) {
+                    ivBytes = ((RC2ParameterSpec)params).getIV();
+                    if ((ivBytes != null) && (ivBytes.length != blockSize)) {
+                        throw new InvalidAlgorithmParameterException
+                            ("Wrong IV length: must be " + blockSize +
+                             " bytes long");
+                    }
+                } else {
+                    throw new InvalidAlgorithmParameterException
+                        ("Unsupported parameter: " + params);
+                }
             }
-        } else if (params instanceof RC2ParameterSpec) {
-            ivBytes = ((RC2ParameterSpec)params).getIV();
-            if ((ivBytes != null) && (ivBytes.length != blockSize)) {
-                throw new InvalidAlgorithmParameterException
-                    ("Wrong IV length: must be " + blockSize +
-                    " bytes long");
-            }
-        } else {
-            throw new InvalidAlgorithmParameterException("Wrong parameter "
-                                                         + "type: IV "
-                                                         + "expected");
         }
-
         if (cipherMode == ECB_MODE) {
             if (ivBytes != null) {
                 throw new InvalidAlgorithmParameterException
                                                 ("ECB mode cannot use IV");
             }
-        } else if (ivBytes == null) {
+        } else if (ivBytes == null)  {
             if (decrypting) {
                 throw new InvalidAlgorithmParameterException("Parameters "
                                                              + "missing");
             }
+
             if (random == null) {
-                random = SunJCE.RANDOM;
+                random = SunJCE.getRandom();
             }
-            ivBytes = new byte[blockSize];
+            if (cipherMode == GCM_MODE) {
+                ivBytes = new byte[GaloisCounterMode.DEFAULT_IV_LEN];
+            } else {
+                ivBytes = new byte[blockSize];
+            }
             random.nextBytes(ivBytes);
         }
 
@@ -466,23 +579,57 @@
 
         String algorithm = key.getAlgorithm();
 
-        cipher.init(decrypting, algorithm, keyBytes, ivBytes);
+        // GCM mode needs additional handling
+        if (cipherMode == GCM_MODE) {
+            if(tagLen == -1) {
+                tagLen = GaloisCounterMode.DEFAULT_TAG_LEN;
+            }
+            if (decrypting) {
+                minBytes = tagLen;
+            } else {
+                // check key+iv for encryption in GCM mode
+                requireReinit =
+                    Arrays.equals(ivBytes, lastEncIv) &&
+                    Arrays.equals(keyBytes, lastEncKey);
+                if (requireReinit) {
+                    throw new InvalidAlgorithmParameterException
+                        ("Cannot reuse iv for GCM encryption");
+                }
+                lastEncIv = ivBytes;
+                lastEncKey = keyBytes;
+            }
+            ((GaloisCounterMode) cipher).init
+                (decrypting, algorithm, keyBytes, ivBytes, tagLen);
+        } else {
+            cipher.init(decrypting, algorithm, keyBytes, ivBytes);
+        }
+        // skip checking key+iv from now on until after doFinal()
+        requireReinit = false;
     }
 
     void init(int opmode, Key key, AlgorithmParameters params,
               SecureRandom random)
         throws InvalidKeyException, InvalidAlgorithmParameterException {
-        IvParameterSpec ivSpec = null;
+        AlgorithmParameterSpec spec = null;
+        String paramType = null;
         if (params != null) {
             try {
-                ivSpec = params.getParameterSpec(IvParameterSpec.class);
+                if (cipherMode == GCM_MODE) {
+                    paramType = "GCM";
+                    spec = params.getParameterSpec(GCMParameterSpec.class);
+                } else {
+                    // NOTE: RC2 parameters are always handled through
+                    // init(..., AlgorithmParameterSpec,...) method, so
+                    // we can assume IvParameterSpec type here.
+                    paramType = "IV";
+                    spec = params.getParameterSpec(IvParameterSpec.class);
+                }
             } catch (InvalidParameterSpecException ipse) {
-                throw new InvalidAlgorithmParameterException("Wrong parameter "
-                                                             + "type: IV "
-                                                             + "expected");
+                throw new InvalidAlgorithmParameterException
+                    ("Wrong parameter type: " + paramType + " expected");
             }
         }
-        init(opmode, key, ivSpec, random);
+        init(opmode, key, spec, random);
     }
 
     /**
@@ -504,6 +651,7 @@
         return keyBytes;
     }
 
+
     /**
      * Continues a multiple-part encryption or decryption operation
      * (depending on how this cipher was initialized), processing another data
@@ -524,22 +672,25 @@
      * (e.g., has not been initialized)
      */
     byte[] update(byte[] input, int inputOffset, int inputLen) {
+        if (requireReinit) {
+            throw new IllegalStateException
+                ("Must use either different key or iv for GCM encryption");
+        }
+
         byte[] output = null;
-        byte[] out = null;
         try {
-            output = new byte[getOutputSize(inputLen)];
+            output = new byte[getOutputSizeByOperation(inputLen, false)];
             int len = update(input, inputOffset, inputLen, output,
                              0);
             if (len == output.length) {
-                out = output;
+                return output;
             } else {
-                out = new byte[len];
-                System.arraycopy(output, 0, out, 0, len);
+                return Arrays.copyOf(output, len);
             }
         } catch (ShortBufferException e) {
-            // never thrown
+            // should never happen
+            throw new ProviderException("Unexpected exception", e);
         }
-        return out;
     }
 
     /**
@@ -567,6 +718,11 @@
      */
     int update(byte[] input, int inputOffset, int inputLen, byte[] output,
                int outputOffset) throws ShortBufferException {
+        if (requireReinit) {
+            throw new IllegalStateException
+                ("Must use either different key or iv for GCM encryption");
+        }
+
         // figure out how much can be sent to crypto function
         int len = buffered + inputLen - minBytes;
         if (padding != null && decrypting) {
@@ -582,6 +738,7 @@
                                            + "(at least) " + len
                                            + " bytes long");
         }
+
         if (len != 0) {
             // there is some work to do
             byte[] in = new byte[len];
@@ -600,7 +757,6 @@
                 System.arraycopy(input, inputOffset, in,
                                  bufferedConsumed, inputConsumed);
             }
-
             if (decrypting) {
                 cipher.decrypt(in, 0, len, output, outputOffset);
             } else {
@@ -611,11 +767,12 @@
             // the total input length a multiple of blocksize when
             // padding is applied
             if (unitBytes != blockSize) {
-                if (len < diffBlocksize)
+                if (len < diffBlocksize) {
                     diffBlocksize -= len;
-                else
+                } else {
                     diffBlocksize = blockSize -
                         ((len - diffBlocksize) % blockSize);
+                }
             }
 
             inputLen -= inputConsumed;
@@ -669,21 +826,18 @@
     byte[] doFinal(byte[] input, int inputOffset, int inputLen)
         throws IllegalBlockSizeException, BadPaddingException {
         byte[] output = null;
-        byte[] out = null;
         try {
-            output = new byte[getOutputSize(inputLen)];
+            output = new byte[getOutputSizeByOperation(inputLen, true)];
             int len = doFinal(input, inputOffset, inputLen, output, 0);
             if (len < output.length) {
-                out = new byte[len];
-                if (len != 0)
-                    System.arraycopy(output, 0, out, 0, len);
+                return Arrays.copyOf(output, len);
             } else {
-                out = output;
+                return output;
             }
         } catch (ShortBufferException e) {
             // never thrown
+            throw new ProviderException("Unexpected exception", e);
         }
-        return out;
     }
 
     /**
@@ -726,6 +880,10 @@
                 int outputOffset)
         throws IllegalBlockSizeException, ShortBufferException,
                BadPaddingException {
+        if (requireReinit) {
+            throw new IllegalStateException
+                ("Must use either different key or iv for GCM encryption");
+        }
 
         // calculate the total input length
         int totalLen = buffered + inputLen;
@@ -752,8 +910,9 @@
         }
 
         // if encrypting and padding not null, add padding
-        if (!decrypting && padding != null)
+        if (!decrypting && padding != null) {
             paddedLen += paddingLen;
+        }
 
         // check output buffer capacity.
         // if we are decrypting with padding applied, we can perform this
@@ -763,8 +922,8 @@
             throw new ShortBufferException("Output buffer is null");
         }
         int outputCapacity = output.length - outputOffset;
-        if (((!decrypting) || (padding == null)) &&
-            (outputCapacity < paddedLen) ||
+
+        if (((!decrypting) && (outputCapacity < paddedLen)) ||
             (decrypting && (outputCapacity < (paddedLen - blockSize)))) {
             throw new ShortBufferException("Output buffer too short: "
                                            + outputCapacity + " bytes given, "
@@ -812,6 +971,7 @@
                 }
                 totalLen = padStart;
             }
+
             if ((output.length - outputOffset) < totalLen) {
                 // restore so users can retry with a larger buffer
                 cipher.restore();
@@ -824,8 +984,13 @@
                 output[outputOffset + i] = outWithPadding[i];
             }
         } else { // encrypting
-            totalLen = finalNoPadding(finalBuf, finalOffset, output,
-                                      outputOffset, paddedLen);
+            try {
+                totalLen = finalNoPadding(finalBuf, finalOffset, output,
+                                          outputOffset, paddedLen);
+            } finally {
+                // reset after doFinal() for GCM encryption
+                requireReinit = (cipherMode == GCM_MODE);
+            }
         }
 
         buffered = 0;
@@ -836,33 +1001,33 @@
         return totalLen;
     }
 
-    private int finalNoPadding(byte[] in, int inOff, byte[] out, int outOff,
+    private int finalNoPadding(byte[] in, int inOfs, byte[] out, int outOfs,
                                int len)
-        throws IllegalBlockSizeException
-    {
-        if (in == null || len == 0)
-            return 0;
+        throws IllegalBlockSizeException, AEADBadTagException {
 
-        if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE)
-            && ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) {
-            if (padding != null) {
-                throw new IllegalBlockSizeException
-                    ("Input length (with padding) not multiple of " +
-                     unitBytes + " bytes");
-            } else {
-                throw new IllegalBlockSizeException
-                    ("Input length not multiple of " + unitBytes
-                     + " bytes");
-            }
+        if ((cipherMode != GCM_MODE) && (in == null || len == 0)) {
+            return 0;
         }
-
+        if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE) &&
+            (cipherMode != GCM_MODE) &&
+            ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) {
+                if (padding != null) {
+                    throw new IllegalBlockSizeException
+                        ("Input length (with padding) not multiple of " +
+                         unitBytes + " bytes");
+                } else {
+                    throw new IllegalBlockSizeException
+                        ("Input length not multiple of " + unitBytes
+                         + " bytes");
+                }
+        }
+        int outLen = 0;
         if (decrypting) {
-            cipher.decryptFinal(in, inOff, len, out, outOff);
+            outLen = cipher.decryptFinal(in, inOfs, len, out, outOfs);
         } else {
-            cipher.encryptFinal(in, inOff, len, out, outOff);
+            outLen = cipher.encryptFinal(in, inOfs, len, out, outOfs);
         }
-
-        return len;
+        return outLen;
     }
 
     // Note: Wrap() and Unwrap() are the same in
@@ -939,4 +1104,36 @@
         return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
                                           wrappedKeyType);
     }
+
+    /**
+     * Continues a multi-part update of the Additional Authentication
+     * Data (AAD), using a subset of the provided buffer.
+     * <p>
+     * Calls to this method provide AAD to the cipher when operating in
+     * modes such as AEAD (GCM/CCM).  If this cipher is operating in
+     * either GCM or CCM mode, all AAD must be supplied before beginning
+     * operations on the ciphertext (via the {@code update} and {@code
+     * doFinal} methods).
+     *
+     * @param src the buffer containing the AAD
+     * @param offset the offset in {@code src} where the AAD input starts
+     * @param len the number of AAD bytes
+     *
+     * @throws IllegalStateException if this cipher is in a wrong state
+     * (e.g., has not been initialized), does not accept AAD, or if
+     * operating in either GCM or CCM mode and one of the {@code update}
+     * methods has already been called for the active
+     * encryption/decryption operation
+     * @throws UnsupportedOperationException if this method
+     * has not been overridden by an implementation
+     *
+     * @since 1.8
+     */
+    void updateAAD(byte[] src, int offset, int len) {
+        if (requireReinit) {
+            throw new IllegalStateException
+                ("Must use either different key or iv for GCM encryption");
+        }
+        cipher.updateAAD(src, offset, len);
+    }
 }
--- a/jdk/src/share/classes/com/sun/crypto/provider/CipherTextStealing.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/CipherTextStealing.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -83,9 +83,10 @@
      * @param plainLen the length of the input data
      * @param cipher the buffer for the result
      * @param cipherOffset the offset in <code>cipher</code>
+     * @return the number of bytes placed into <code>cipher</code>
      */
-    void encryptFinal(byte[] plain, int plainOffset, int plainLen,
-                      byte[] cipher, int cipherOffset)
+    int encryptFinal(byte[] plain, int plainOffset, int plainLen,
+                     byte[] cipher, int cipherOffset)
         throws IllegalBlockSizeException {
 
         if (plainLen < blockSize) {
@@ -134,6 +135,7 @@
                 embeddedCipher.encryptBlock(tmp2, 0, cipher, cipherOffset);
             }
         }
+        return plainLen;
     }
 
     /**
@@ -158,9 +160,10 @@
      * @param cipherLen the length of the input data
      * @param plain the buffer for the result
      * @param plainOffset the offset in <code>plain</code>
+     * @return the number of bytes placed into <code>plain</code>
      */
-    void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
-                      byte[] plain, int plainOffset)
+    int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
+                     byte[] plain, int plainOffset)
         throws IllegalBlockSizeException {
         if (cipherLen < blockSize) {
             throw new IllegalBlockSizeException("input is too short!");
@@ -211,5 +214,6 @@
                 }
             }
         }
+        return cipherLen;
     }
 }
--- a/jdk/src/share/classes/com/sun/crypto/provider/DESKeyGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DESKeyGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,7 @@
         DESKey desKey = null;
 
         if (this.random == null) {
-            this.random = SunJCE.RANDOM;
+            this.random = SunJCE.getRandom();
         }
 
         try {
--- a/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -105,7 +105,7 @@
      */
     protected SecretKey engineGenerateKey() {
         if (this.random == null) {
-            this.random = SunJCE.RANDOM;
+            this.random = SunJCE.getRandom();
         }
 
         byte[] rawkey = new byte[DESedeKeySpec.DES_EDE_KEY_LEN];
--- a/jdk/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -217,7 +217,7 @@
             if (params == null) {
                 iv = new byte[8];
                 if (random == null) {
-                    random = SunJCE.RANDOM;
+                    random = SunJCE.getRandom();
                 }
                 random.nextBytes(iv);
             }
--- a/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,7 +140,7 @@
      */
     public KeyPair generateKeyPair() {
         if (random == null) {
-            random = SunJCE.RANDOM;
+            random = SunJCE.getRandom();
         }
 
         if (params == null) {
--- a/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DHParameterGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -131,7 +131,7 @@
         }
 
         if (this.random == null)
-            this.random = SunJCE.RANDOM;
+            this.random = SunJCE.getRandom();
 
         try {
             AlgorithmParameterGenerator paramGen;
--- a/jdk/src/share/classes/com/sun/crypto/provider/FeedbackCipher.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/FeedbackCipher.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
-import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.*;
 
 /**
  * This class represents a block cipher in one of its modes. It wraps
@@ -150,11 +150,13 @@
      * @param plainLen the length of the input data
      * @param cipher the buffer for the encryption result
      * @param cipherOffset the offset in <code>cipher</code>
+     * @return the number of bytes placed into <code>cipher</code>
      */
-     void encryptFinal(byte[] plain, int plainOffset, int plainLen,
-                       byte[] cipher, int cipherOffset)
+     int encryptFinal(byte[] plain, int plainOffset, int plainLen,
+                      byte[] cipher, int cipherOffset)
          throws IllegalBlockSizeException {
          encrypt(plain, plainOffset, plainLen, cipher, cipherOffset);
+         return plainLen;
      }
     /**
      * Performs decryption operation.
@@ -190,10 +192,40 @@
      * @param cipherLen the length of the input data
      * @param plain the buffer for the decryption result
      * @param plainOffset the offset in <code>plain</code>
+     * @return the number of bytes placed into <code>plain</code>
      */
-     void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
-                       byte[] plain, int plainOffset)
-         throws IllegalBlockSizeException {
+     int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
+                      byte[] plain, int plainOffset)
+         throws IllegalBlockSizeException, AEADBadTagException {
          decrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
+         return cipherLen;
      }
+
+    /**
+     * Continues a multi-part update of the Additional Authentication
+     * Data (AAD), using a subset of the provided buffer. If this
+     * cipher is operating in either GCM or CCM mode, all AAD must be
+     * supplied before beginning operations on the ciphertext (via the
+     * {@code update} and {@code doFinal} methods).
+     * <p>
+     * NOTE: Given most modes do not accept AAD, default impl for this
+     * method throws IllegalStateException.
+     *
+     * @param src the buffer containing the AAD
+     * @param offset the offset in {@code src} where the AAD input starts
+     * @param len the number of AAD bytes
+     *
+     * @throws IllegalStateException if this cipher is in a wrong state
+     * (e.g., has not been initialized), does not accept AAD, or if
+     * operating in either GCM or CCM mode and one of the {@code update}
+     * methods has already been called for the active
+     * encryption/decryption operation
+     * @throws UnsupportedOperationException if this method
+     * has not been overridden by an implementation
+     *
+     * @since 1.8
+     */
+    void updateAAD(byte[] src, int offset, int len) {
+        throw new IllegalStateException("No AAD accepted");
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/crypto/provider/GCMParameters.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.crypto.provider;
+
+import java.io.IOException;
+import java.security.AlgorithmParametersSpi;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import javax.crypto.spec.GCMParameterSpec;
+import sun.misc.HexDumpEncoder;
+import sun.security.util.*;
+
+/**
+ * This class implements the parameter set used with
+ * GCM encryption, which is defined in RFC 5084 as follows:
+ *
+ * <pre>
+ *    GCMParameters ::= SEQUENCE {
+ *      aes-iv      OCTET STRING, -- recommended size is 12 octets
+ *      aes-tLen    AES-GCM-ICVlen DEFAULT 12 }
+ *
+ *    AES-GCM-ICVlen ::= INTEGER (12 | 13 | 14 | 15 | 16)
+ *
+ * </pre>
+ *
+ * @author Valerie Peng
+ * @since 1.8
+ */
+public final class GCMParameters extends AlgorithmParametersSpi {
+
+    // the iv
+    private byte[] iv;
+    // the tag length in bytes
+    private int tLen;
+
+    public GCMParameters() {}
+
+    protected void engineInit(AlgorithmParameterSpec paramSpec)
+        throws InvalidParameterSpecException {
+
+        if (!(paramSpec instanceof GCMParameterSpec)) {
+            throw new InvalidParameterSpecException
+                ("Inappropriate parameter specification");
+        }
+        GCMParameterSpec gps = (GCMParameterSpec) paramSpec;
+        // need to convert from bits to bytes for ASN.1 encoding
+        this.tLen = gps.getTLen()/8;
+        this.iv = gps.getIV();
+    }
+
+    protected void engineInit(byte[] encoded) throws IOException {
+        DerValue val = new DerValue(encoded);
+        // check if IV or params
+        if (val.tag == DerValue.tag_Sequence) {
+            byte[] iv = val.data.getOctetString();
+            int tLen;
+            if (val.data.available() != 0) {
+                tLen = val.data.getInteger();
+                if (tLen < 12 || tLen > 16 ) {
+                    throw new IOException
+                        ("GCM parameter parsing error: unsupported tag len: " +
+                         tLen);
+                }
+                if (val.data.available() != 0) {
+                    throw new IOException
+                        ("GCM parameter parsing error: extra data");
+                }
+            } else {
+                tLen = 12;
+            }
+            this.iv = iv.clone();
+            this.tLen = tLen;
+        } else {
+            throw new IOException("GCM parameter parsing error: no SEQ tag");
+        }
+    }
+
+    protected void engineInit(byte[] encoded, String decodingMethod)
+        throws IOException {
+        engineInit(encoded);
+    }
+
+    protected <T extends AlgorithmParameterSpec>
+            T engineGetParameterSpec(Class<T> paramSpec)
+        throws InvalidParameterSpecException {
+
+        if (GCMParameterSpec.class.isAssignableFrom(paramSpec)) {
+            return paramSpec.cast(new GCMParameterSpec(tLen * 8, iv));
+        } else {
+            throw new InvalidParameterSpecException
+                ("Inappropriate parameter specification");
+        }
+    }
+
+    protected byte[] engineGetEncoded() throws IOException {
+        DerOutputStream out = new DerOutputStream();
+        DerOutputStream bytes = new DerOutputStream();
+
+        bytes.putOctetString(iv);
+        bytes.putInteger(tLen);
+        out.write(DerValue.tag_Sequence, bytes);
+        return out.toByteArray();
+    }
+
+    protected byte[] engineGetEncoded(String encodingMethod)
+        throws IOException {
+        return engineGetEncoded();
+    }
+
+    /*
+     * Returns a formatted string describing the parameters.
+     */
+    protected String engineToString() {
+        String LINE_SEP = System.getProperty("line.separator");
+        HexDumpEncoder encoder = new HexDumpEncoder();
+        StringBuilder sb
+            = new StringBuilder(LINE_SEP + "    iv:" + LINE_SEP + "["
+                + encoder.encodeBuffer(iv) + "]");
+
+        sb.append(LINE_SEP + "tLen(bits):" + LINE_SEP + tLen*8 + LINE_SEP);
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/crypto/provider/GCTR.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * (C) Copyright IBM Corp. 2013
+ */
+
+package com.sun.crypto.provider;
+
+import java.security.*;
+import javax.crypto.*;
+import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+
+/**
+ * This class represents the GCTR function defined in NIST 800-38D
+ * under section 6.5. It needs to be constructed w/ an initialized
+ * cipher object, and initial counter block(ICB). Given an input X
+ * of arbitrary length, it processes and returns an output which has
+ * the same length as X.
+ *
+ * <p>This function is used in the implementation of GCM mode.
+ *
+ * @since 1.8
+ */
+final class GCTR {
+
+    // these fields should not change after the object has been constructed
+    private final SymmetricCipher aes;
+    private final byte[] icb;
+
+    // the current counter value
+    private byte[] counter;
+
+    // needed for save/restore calls
+    private byte[] counterSave;
+
+    // NOTE: cipher should already be initialized
+    GCTR(SymmetricCipher cipher, byte[] initialCounterBlk) {
+        this.aes = cipher;
+        this.icb = initialCounterBlk;
+        this.counter = icb.clone();
+    }
+
+    // input must be multiples of 128-bit blocks when calling update
+    int update(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
+        if (inLen - inOfs > in.length) {
+            throw new RuntimeException("input length out of bound");
+        }
+        if (inLen < 0 || inLen % AES_BLOCK_SIZE != 0) {
+            throw new RuntimeException("input length unsupported");
+        }
+        if (out.length - outOfs < inLen) {
+            throw new RuntimeException("output buffer too small");
+        }
+
+        byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
+
+        int numOfCompleteBlocks = inLen / AES_BLOCK_SIZE;
+        for (int i = 0; i < numOfCompleteBlocks; i++) {
+            aes.encryptBlock(counter, 0, encryptedCntr, 0);
+            for (int n = 0; n < AES_BLOCK_SIZE; n++) {
+                int index = (i * AES_BLOCK_SIZE + n);
+                out[outOfs + index] =
+                    (byte) ((in[inOfs + index] ^ encryptedCntr[n]));
+            }
+            GaloisCounterMode.increment32(counter);
+        }
+        return inLen;
+    }
+
+    // input can be arbitrary size when calling doFinal
+    protected int doFinal(byte[] in, int inOfs, int inLen, byte[] out,
+                          int outOfs) throws IllegalBlockSizeException {
+        try {
+            if (inLen < 0) {
+                throw new IllegalBlockSizeException("Negative input size!");
+            } else if (inLen > 0) {
+                int lastBlockSize = inLen % AES_BLOCK_SIZE;
+                // process the complete blocks first
+                update(in, inOfs, inLen - lastBlockSize, out, outOfs);
+                if (lastBlockSize != 0) {
+                    // do the last partial block
+                    byte[] encryptedCntr = new byte[AES_BLOCK_SIZE];
+                    aes.encryptBlock(counter, 0, encryptedCntr, 0);
+
+                    int processed = inLen - lastBlockSize;
+                    for (int n = 0; n < lastBlockSize; n++) {
+                        out[outOfs + processed + n] =
+                            (byte) ((in[inOfs + processed + n] ^
+                                     encryptedCntr[n]));
+                    }
+                }
+            }
+        } finally {
+            reset();
+        }
+        return inLen;
+    }
+
+    /**
+     * Resets the current counter to its initial value.
+     * This is used after the doFinal() is called so this object can be
+     * reused w/o explicit re-initialization.
+     */
+    void reset() {
+        System.arraycopy(icb, 0, counter, 0, icb.length);
+    }
+
+    /**
+     * Save the current content of this object.
+     */
+    void save() {
+        this.counterSave = this.counter.clone();
+    }
+
+    /**
+     * Restores the content of this object to the previous saved one.
+     */
+    void restore() {
+        this.counter = this.counterSave;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/crypto/provider/GHASH.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * (C) Copyright IBM Corp. 2013
+ */
+
+package com.sun.crypto.provider;
+
+import java.util.Arrays;
+import java.security.*;
+import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+
+/**
+ * This class represents the GHASH function defined in NIST 800-38D
+ * under section 6.4. It needs to be constructed w/ a hash subkey, i.e.
+ * block H. Given input of 128-bit blocks, it will process and output
+ * a 128-bit block.
+ *
+ * <p>This function is used in the implementation of GCM mode.
+ *
+ * @since 1.8
+ */
+final class GHASH {
+
+    private static final byte P128 = (byte) 0xe1; //reduction polynomial
+
+    private static boolean getBit(byte[] b, int pos) {
+        int p = pos / 8;
+        pos %= 8;
+        int i = (b[p] >>> (7 - pos)) & 1;
+        return i != 0;
+    }
+
+    private static void shift(byte[] b) {
+        byte temp, temp2;
+        temp2 = 0;
+        for (int i = 0; i < b.length; i++) {
+            temp = (byte) ((b[i] & 0x01) << 7);
+            b[i] = (byte) ((b[i] & 0xff) >>> 1);
+            b[i] = (byte) (b[i] | temp2);
+            temp2 = temp;
+        }
+    }
+
+    // Given block X and Y, returns the muliplication of X * Y
+    private static byte[] blockMult(byte[] x, byte[] y) {
+        if (x.length != AES_BLOCK_SIZE || y.length != AES_BLOCK_SIZE) {
+            throw new RuntimeException("illegal input sizes");
+        }
+        byte[] z = new byte[AES_BLOCK_SIZE];
+        byte[] v = y.clone();
+        // calculate Z1-Z127 and V1-V127
+        for (int i = 0; i < 127; i++) {
+            // Zi+1 = Zi if bit i of x is 0
+            if (getBit(x, i)) {
+                for (int n = 0; n < z.length; n++) {
+                    z[n] ^= v[n];
+                }
+            }
+            boolean lastBitOfV = getBit(v, 127);
+            shift(v);
+            if (lastBitOfV) v[0] ^= P128;
+        }
+        // calculate Z128
+        if (getBit(x, 127)) {
+            for (int n = 0; n < z.length; n++) {
+                z[n] ^= v[n];
+            }
+        }
+        return z;
+    }
+
+    // hash subkey H; should not change after the object has been constructed
+    private final byte[] subkeyH;
+
+    // buffer for storing hash
+    private byte[] state;
+
+    // variables for save/restore calls
+    private byte[] stateSave = null;
+
+    /**
+     * Initializes the cipher in the specified mode with the given key
+     * and iv.
+     *
+     * @param subkeyH the hash subkey
+     *
+     * @exception ProviderException if the given key is inappropriate for
+     * initializing this digest
+     */
+    GHASH(byte[] subkeyH) throws ProviderException {
+        if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
+            throw new ProviderException("Internal error");
+        }
+        this.subkeyH = subkeyH;
+        this.state = new byte[AES_BLOCK_SIZE];
+    }
+
+    /**
+     * Resets the GHASH object to its original state, i.e. blank w/
+     * the same subkey H. Used after digest() is called and to re-use
+     * this object for different data w/ the same H.
+     */
+    void reset() {
+        Arrays.fill(state, (byte) 0);
+    }
+
+    /**
+     * Save the current snapshot of this GHASH object.
+     */
+    void save() {
+        stateSave = state.clone();
+    }
+
+    /**
+     * Restores this object using the saved snapshot.
+     */
+    void restore() {
+        state = stateSave;
+    }
+
+    private void processBlock(byte[] data, int ofs) {
+        if (data.length - ofs < AES_BLOCK_SIZE) {
+            throw new RuntimeException("need complete block");
+        }
+        for (int n = 0; n < state.length; n++) {
+            state[n] ^= data[ofs + n];
+        }
+        state = blockMult(state, subkeyH);
+    }
+
+    void update(byte[] in) {
+        update(in, 0, in.length);
+    }
+
+    void update(byte[] in, int inOfs, int inLen) {
+        if (inLen - inOfs > in.length) {
+            throw new RuntimeException("input length out of bound");
+        }
+        if (inLen % AES_BLOCK_SIZE != 0) {
+            throw new RuntimeException("input length unsupported");
+        }
+
+        for (int i = inOfs; i < (inOfs + inLen); i += AES_BLOCK_SIZE) {
+            processBlock(in, i);
+        }
+    }
+
+    byte[] digest() {
+        try {
+            return state.clone();
+        } finally {
+            reset();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.S
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.crypto.provider;
+
+import java.util.Arrays;
+import java.io.*;
+import java.security.*;
+import javax.crypto.*;
+import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+
+/**
+ * This class represents ciphers in GaloisCounter (GCM) mode.
+ *
+ * <p>This mode currently should only be used w/ AES cipher.
+ * Although no checking is done here, caller should only
+ * pass AES Cipher to the constructor.
+ *
+ * <p>NOTE: This class does not deal with buffering or padding.
+ *
+ * @since 1.8
+ */
+final class GaloisCounterMode extends FeedbackCipher {
+
+    static int DEFAULT_TAG_LEN = AES_BLOCK_SIZE;
+    static int DEFAULT_IV_LEN = 12; // in bytes
+
+    // buffer for AAD data; if null, meaning update has been called
+    private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
+    private int sizeOfAAD = 0;
+
+    // in bytes; need to convert to bits (default value 128) when needed
+    private int tagLenBytes = DEFAULT_TAG_LEN;
+
+    // these following 2 fields can only be initialized after init() is
+    // called, e.g. after cipher key k is set, and STAY UNCHANGED
+    private byte[] subkeyH = null;
+    private byte[] preCounterBlock = null;
+
+    private GCTR gctrPAndC = null;
+    private GHASH ghashAllToS = null;
+
+    // length of total data, i.e. len(C)
+    private int processed = 0;
+
+    // additional variables for save/restore calls
+    private byte[] aadBufferSave = null;
+    private int sizeOfAADSave = 0;
+    private int processedSave = 0;
+
+    // value must be 16-byte long; used by GCTR and GHASH as well
+    static void increment32(byte[] value) {
+        if (value.length != AES_BLOCK_SIZE) {
+            throw new RuntimeException("Unexpected counter block length");
+        }
+        // start from last byte and only go over 4 bytes, i.e. total 32 bits
+        int n = value.length - 1;
+        while ((n >= value.length - 4) && (++value[n] == 0)) {
+            n--;
+        }
+    }
+
+    // ivLen in bits
+    private static byte[] getLengthBlock(int ivLen) {
+        byte[] out = new byte[AES_BLOCK_SIZE];
+        out[12] = (byte)(ivLen >>> 24);
+        out[13] = (byte)(ivLen >>> 16);
+        out[14] = (byte)(ivLen >>> 8);
+        out[15] = (byte)ivLen;
+        return out;
+    }
+
+    // aLen and cLen both in bits
+    private static byte[] getLengthBlock(int aLen, int cLen) {
+        byte[] out = new byte[AES_BLOCK_SIZE];
+        out[4] = (byte)(aLen >>> 24);
+        out[5] = (byte)(aLen >>> 16);
+        out[6] = (byte)(aLen >>> 8);
+        out[7] = (byte)aLen;
+        out[12] = (byte)(cLen >>> 24);
+        out[13] = (byte)(cLen >>> 16);
+        out[14] = (byte)(cLen >>> 8);
+        out[15] = (byte)cLen;
+        return out;
+    }
+
+    private static byte[] expandToOneBlock(byte[] in, int inOfs, int len) {
+        if (len > AES_BLOCK_SIZE) {
+            throw new ProviderException("input " + len + " too long");
+        }
+        if (len == AES_BLOCK_SIZE && inOfs == 0) {
+            return in;
+        } else {
+            byte[] paddedIn = new byte[AES_BLOCK_SIZE];
+            System.arraycopy(in, inOfs, paddedIn, 0, len);
+            return paddedIn;
+        }
+    }
+
+    private static byte[] getJ0(byte[] iv, byte[] subkeyH) {
+        byte[] j0;
+        if (iv.length == 12) { // 96 bits
+            j0 = expandToOneBlock(iv, 0, iv.length);
+            j0[AES_BLOCK_SIZE - 1] = 1;
+        } else {
+            GHASH g = new GHASH(subkeyH);
+            int lastLen = iv.length % AES_BLOCK_SIZE;
+            if (lastLen != 0) {
+                g.update(iv, 0, iv.length - lastLen);
+                byte[] padded =
+                    expandToOneBlock(iv, iv.length - lastLen, lastLen);
+                g.update(padded);
+            } else {
+                g.update(iv);
+            }
+            byte[] lengthBlock = getLengthBlock(iv.length*8);
+            g.update(lengthBlock);
+            j0 = g.digest();
+        }
+        return j0;
+    }
+
+    GaloisCounterMode(SymmetricCipher embeddedCipher) {
+        super(embeddedCipher);
+        aadBuffer = new ByteArrayOutputStream();
+    }
+
+    /**
+     * Gets the name of the feedback mechanism
+     *
+     * @return the name of the feedback mechanism
+     */
+    String getFeedback() {
+        return "GCM";
+    }
+
+    /**
+     * Resets the cipher object to its original state.
+     * This is used when doFinal is called in the Cipher class, so that the
+     * cipher can be reused (with its original key and iv).
+     */
+    void reset() {
+        if (aadBuffer == null) {
+            aadBuffer = new ByteArrayOutputStream();
+        } else {
+            aadBuffer.reset();
+        }
+        if (gctrPAndC != null) gctrPAndC.reset();
+        if (ghashAllToS != null) ghashAllToS.reset();
+        processed = 0;
+        sizeOfAAD = 0;
+    }
+
+    /**
+     * Save the current content of this cipher.
+     */
+    void save() {
+        processedSave = processed;
+        sizeOfAADSave = sizeOfAAD;
+        aadBufferSave =
+            ((aadBuffer == null || aadBuffer.size() == 0)?
+             null : aadBuffer.toByteArray());
+        if (gctrPAndC != null) gctrPAndC.save();
+        if (ghashAllToS != null) ghashAllToS.save();
+    }
+
+    /**
+     * Restores the content of this cipher to the previous saved one.
+     */
+    void restore() {
+        processed = processedSave;
+        sizeOfAAD = sizeOfAADSave;
+        if (aadBuffer != null) {
+            aadBuffer.reset();
+            if (aadBufferSave != null) {
+                aadBuffer.write(aadBufferSave, 0, aadBufferSave.length);
+            }
+        }
+       if (gctrPAndC != null) gctrPAndC.restore();
+       if (ghashAllToS != null) ghashAllToS.restore();
+    }
+
+    /**
+     * Initializes the cipher in the specified mode with the given key
+     * and iv.
+     *
+     * @param decrypting flag indicating encryption or decryption
+     * @param algorithm the algorithm name
+     * @param key the key
+     * @param iv the iv
+     * @param tagLenBytes the length of tag in bytes
+     *
+     * @exception InvalidKeyException if the given key is inappropriate for
+     * initializing this cipher
+     */
+    void init(boolean decrypting, String algorithm, byte[] key, byte[] iv)
+            throws InvalidKeyException {
+        init(decrypting, algorithm, key, iv, DEFAULT_TAG_LEN);
+    }
+
+    /**
+     * Initializes the cipher in the specified mode with the given key
+     * and iv.
+     *
+     * @param decrypting flag indicating encryption or decryption
+     * @param algorithm the algorithm name
+     * @param key the key
+     * @param iv the iv
+     * @param tagLenBytes the length of tag in bytes
+     *
+     * @exception InvalidKeyException if the given key is inappropriate for
+     * initializing this cipher
+     */
+    void init(boolean decrypting, String algorithm, byte[] keyValue,
+              byte[] ivValue, int tagLenBytes)
+              throws InvalidKeyException {
+        if (keyValue == null || ivValue == null) {
+            throw new InvalidKeyException("Internal error");
+        }
+
+        // always encrypt mode for embedded cipher
+        this.embeddedCipher.init(false, algorithm, keyValue);
+        this.subkeyH = new byte[AES_BLOCK_SIZE];
+        this.embeddedCipher.encryptBlock(new byte[AES_BLOCK_SIZE], 0,
+                this.subkeyH, 0);
+
+        this.iv = ivValue.clone();
+        preCounterBlock = getJ0(iv, subkeyH);
+        byte[] j0Plus1 = preCounterBlock.clone();
+        increment32(j0Plus1);
+        gctrPAndC = new GCTR(embeddedCipher, j0Plus1);
+        ghashAllToS = new GHASH(subkeyH);
+
+        this.tagLenBytes = tagLenBytes;
+        if (aadBuffer == null) {
+            aadBuffer = new ByteArrayOutputStream();
+        } else {
+            aadBuffer.reset();
+        }
+        processed = 0;
+        sizeOfAAD = 0;
+    }
+
+    /**
+     * Continues a multi-part update of the Additional Authentication
+     * Data (AAD), using a subset of the provided buffer. If this
+     * cipher is operating in either GCM or CCM mode, all AAD must be
+     * supplied before beginning operations on the ciphertext (via the
+     * {@code update} and {@code doFinal} methods).
+     * <p>
+     * NOTE: Given most modes do not accept AAD, default impl for this
+     * method throws IllegalStateException.
+     *
+     * @param src the buffer containing the AAD
+     * @param offset the offset in {@code src} where the AAD input starts
+     * @param len the number of AAD bytes
+     *
+     * @throws IllegalStateException if this cipher is in a wrong state
+     * (e.g., has not been initialized), does not accept AAD, or if
+     * operating in either GCM or CCM mode and one of the {@code update}
+     * methods has already been called for the active
+     * encryption/decryption operation
+     * @throws UnsupportedOperationException if this method
+     * has not been overridden by an implementation
+     *
+     * @since 1.8
+     */
+    void updateAAD(byte[] src, int offset, int len) {
+        if (aadBuffer != null) {
+            aadBuffer.write(src, offset, len);
+        } else {
+            // update has already been called
+            throw new IllegalStateException
+                ("Update has been called; no more AAD data");
+        }
+    }
+
+    // Feed the AAD data to GHASH, pad if necessary
+    void processAAD() {
+        if (aadBuffer != null) {
+            byte[] aad = aadBuffer.toByteArray();
+            sizeOfAAD = aad.length;
+            aadBuffer = null;
+
+            int lastLen = aad.length % AES_BLOCK_SIZE;
+            if (lastLen != 0) {
+                ghashAllToS.update(aad, 0, aad.length - lastLen);
+                byte[] padded = expandToOneBlock(aad, aad.length - lastLen,
+                                                 lastLen);
+                ghashAllToS.update(padded);
+            } else {
+                ghashAllToS.update(aad);
+            }
+        }
+    }
+
+    // Utility to process the last block; used by encryptFinal and decryptFinal
+    void doLastBlock(byte[] in, int inOfs, int len, byte[] out, int outOfs,
+                     boolean isEncrypt) throws IllegalBlockSizeException {
+        // process data in 'in'
+        gctrPAndC.doFinal(in, inOfs, len, out, outOfs);
+        processed += len;
+
+        byte[] ct;
+        int ctOfs;
+        if (isEncrypt) {
+            ct = out;
+            ctOfs = outOfs;
+        } else {
+            ct = in;
+            ctOfs = inOfs;
+        }
+        int lastLen = len  % AES_BLOCK_SIZE;
+        if (lastLen != 0) {
+            ghashAllToS.update(ct, ctOfs, len - lastLen);
+            byte[] padded =
+                expandToOneBlock(ct, (ctOfs + len - lastLen), lastLen);
+            ghashAllToS.update(padded);
+        } else {
+            ghashAllToS.update(ct, ctOfs, len);
+        }
+    }
+
+
+    /**
+     * Performs encryption operation.
+     *
+     * <p>The input plain text <code>in</code>, starting at <code>inOff</code>
+     * and ending at <code>(inOff + len - 1)</code>, is encrypted. The result
+     * is stored in <code>out</code>, starting at <code>outOfs</code>.
+     *
+     * <p>It is the application's responsibility to make sure that
+     * <code>len</code> is a multiple of the embedded cipher's block size,
+     * otherwise, a ProviderException will be thrown.
+     *
+     * <p>It is also the application's responsibility to make sure that
+     * <code>init</code> has been called before this method is called.
+     * (This check is omitted here, to avoid double checking.)
+     *
+     * @param in the buffer with the input data to be encrypted
+     * @param inOfs the offset in <code>in</code>
+     * @param len the length of the input data
+     * @param out the buffer for the result
+     * @param outOfs the offset in <code>out</code>
+     */
+    void encrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
+        processAAD();
+        if (len > 0) {
+            gctrPAndC.update(in, inOfs, len, out, outOfs);
+            processed += len;
+            ghashAllToS.update(out, outOfs, len);
+        }
+    }
+
+    /**
+     * Performs encryption operation for the last time.
+     *
+     * <p>NOTE: <code>len</code> may not be multiple of the embedded
+     * cipher's block size for this call.
+     *
+     * @param in the input buffer with the data to be encrypted
+     * @param inOfs the offset in <code>in</code>
+     * @param len the length of the input data
+     * @param out the buffer for the encryption result
+     * @param outOfs the offset in <code>out</code>
+     * @return the number of bytes placed into the <code>out</code> buffer
+     */
+     int encryptFinal(byte[] in, int inOfs, int len, byte[] out, int outOfs)
+         throws IllegalBlockSizeException {
+         if (out.length - outOfs < (len + tagLenBytes)) {
+             throw new RuntimeException("Output buffer too small");
+         }
+
+         processAAD();
+         if (len > 0) {
+             //ByteUtil.dumpArray(Arrays.copyOfRange(in, inOfs, inOfs + len));
+             doLastBlock(in, inOfs, len, out, outOfs, true);
+         }
+
+         byte[] lengthBlock = getLengthBlock(sizeOfAAD*8, processed*8);
+         ghashAllToS.update(lengthBlock);
+         byte[] s = ghashAllToS.digest();
+         byte[] sOut = new byte[s.length];
+         GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
+         gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
+
+         System.arraycopy(sOut, 0, out, (outOfs + len), tagLenBytes);
+         return (len + tagLenBytes);
+     }
+
+    /**
+     * Performs decryption operation.
+     *
+     * <p>The input cipher text <code>in</code>, starting at
+     * <code>inOfs</code> and ending at <code>(inOfs + len - 1)</code>,
+     * is decrypted. The result is stored in <code>out</code>, starting at
+     * <code>outOfs</code>.
+     *
+     * <p>It is the application's responsibility to make sure that
+     * <code>len</code> is a multiple of the embedded cipher's block
+     * size, as any excess bytes are ignored.
+     *
+     * <p>It is also the application's responsibility to make sure that
+     * <code>init</code> has been called before this method is called.
+     * (This check is omitted here, to avoid double checking.)
+     *
+     * @param in the buffer with the input data to be decrypted
+     * @param inOfs the offset in <code>in</code>
+     * @param len the length of the input data
+     * @param out the buffer for the result
+     * @param outOfs the offset in <code>out</code>
+     */
+    void decrypt(byte[] in, int inOfs, int len, byte[] out, int outOfs) {
+        processAAD();
+
+        if (len > 0) { // must be at least AES_BLOCK_SIZE bytes long
+            gctrPAndC.update(in, inOfs, len, out, outOfs);
+            processed += len;
+            ghashAllToS.update(in, inOfs, len);
+        }
+    }
+
+    /**
+     * Performs decryption operation for the last time.
+     *
+     * <p>NOTE: For cipher feedback modes which does not perform
+     * special handling for the last few blocks, this is essentially
+     * the same as <code>encrypt(...)</code>. Given most modes do
+     * not do special handling, the default impl for this method is
+     * to simply call <code>decrypt(...)</code>.
+     *
+     * @param in the input buffer with the data to be decrypted
+     * @param inOfs the offset in <code>cipher</code>
+     * @param len the length of the input data
+     * @param out the buffer for the decryption result
+     * @param outOfs the offset in <code>plain</code>
+     * @return the number of bytes placed into the <code>out</code> buffer
+     */
+     int decryptFinal(byte[] in, int inOfs, int len,
+                      byte[] out, int outOfs)
+         throws IllegalBlockSizeException, AEADBadTagException {
+         if (len < tagLenBytes) {
+             throw new RuntimeException("Input buffer too short - need tag");
+         }
+         if (out.length - outOfs < (len - tagLenBytes)) {
+             throw new RuntimeException("Output buffer too small");
+         }
+         processAAD();
+
+         int processedOld = processed;
+         byte[] tag = new byte[tagLenBytes];
+         // get the trailing tag bytes from 'in'
+         System.arraycopy(in, inOfs + len - tagLenBytes, tag, 0, tagLenBytes);
+         len -= tagLenBytes;
+
+         if (len > 0) {
+             doLastBlock(in, inOfs, len, out, outOfs, false);
+         }
+
+         byte[] lengthBlock = getLengthBlock(sizeOfAAD*8, processed*8);
+         ghashAllToS.update(lengthBlock);
+
+         byte[] s = ghashAllToS.digest();
+         byte[] sOut = new byte[s.length];
+         GCTR gctrForSToTag = new GCTR(embeddedCipher, this.preCounterBlock);
+         gctrForSToTag.doFinal(s, 0, s.length, sOut, 0);
+         for (int i = 0; i < tagLenBytes; i++) {
+             if (tag[i] != sOut[i]) {
+                 throw new AEADBadTagException("Tag mismatch!");
+             }
+         }
+         return len;
+     }
+
+    // return tag length in bytes
+    int getTagLen() {
+        return this.tagLenBytes;
+    }
+}
--- a/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
      */
     protected SecretKey engineGenerateKey() {
         if (this.random == null) {
-            this.random = SunJCE.RANDOM;
+            this.random = SunJCE.getRandom();
         }
 
         byte[] keyBytes = new byte[this.keysize];
--- a/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacPKCS12PBESHA1.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -89,7 +89,7 @@
             // generate default for salt and iteration count if necessary
             if (salt == null) {
                 salt = new byte[20];
-                SunJCE.RANDOM.nextBytes(salt);
+                SunJCE.getRandom().nextBytes(salt);
             }
             if (iCount == 0) iCount = 100;
         } else if (!(params instanceof PBEParameterSpec)) {
--- a/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
      */
     protected SecretKey engineGenerateKey() {
         if (this.random == null) {
-            this.random = SunJCE.RANDOM;
+            this.random = SunJCE.getRandom();
         }
 
         byte[] keyBytes = new byte[this.keysize];
--- a/jdk/src/share/classes/com/sun/crypto/provider/ISO10126Padding.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/ISO10126Padding.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,7 +69,7 @@
 
         byte paddingOctet = (byte) (len & 0xff);
         byte[] padding = new byte[len];
-        SunJCE.RANDOM.nextBytes(padding);
+        SunJCE.getRandom().nextBytes(padding);
         padding[len-1] = paddingOctet;
         System.arraycopy(padding, 0, in, off, len);
         return;
--- a/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/KeyGeneratorCore.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
     // generate the key
     SecretKey implGenerateKey() {
         if (random == null) {
-            random = SunJCE.RANDOM;
+            random = SunJCE.getRandom();
         }
         byte[] b = new byte[(keySize + 7) >> 3];
         random.nextBytes(b);
--- a/jdk/src/share/classes/com/sun/crypto/provider/KeyProtector.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/KeyProtector.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -99,7 +99,7 @@
     {
         // create a random salt (8 bytes)
         byte[] salt = new byte[8];
-        SunJCE.RANDOM.nextBytes(salt);
+        SunJCE.getRandom().nextBytes(salt);
 
         // create PBE parameters from salt and iteration count
         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
@@ -284,7 +284,7 @@
     {
         // create a random salt (8 bytes)
         byte[] salt = new byte[8];
-        SunJCE.RANDOM.nextBytes(salt);
+        SunJCE.getRandom().nextBytes(salt);
 
         // create PBE parameters from salt and iteration count
         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, 20);
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBECipherCore.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBECipherCore.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -164,7 +164,7 @@
         AlgorithmParameters params = null;
         if (salt == null) {
             salt = new byte[8];
-            SunJCE.RANDOM.nextBytes(salt);
+            SunJCE.getRandom().nextBytes(salt);
         }
         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
         try {
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBES1Core.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBES1Core.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -164,7 +164,7 @@
         AlgorithmParameters params = null;
         if (salt == null) {
             salt = new byte[8];
-            SunJCE.RANDOM.nextBytes(salt);
+            SunJCE.getRandom().nextBytes(salt);
         }
         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
         try {
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBES2Core.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBES2Core.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -134,13 +134,13 @@
         if (salt == null) {
             // generate random salt and use default iteration count
             salt = new byte[DEFAULT_SALT_LENGTH];
-            SunJCE.RANDOM.nextBytes(salt);
+            SunJCE.getRandom().nextBytes(salt);
             iCount = DEFAULT_COUNT;
         }
         if (ivSpec == null) {
             // generate random IV
             byte[] ivBytes = new byte[blkSize];
-            SunJCE.RANDOM.nextBytes(ivBytes);
+            SunJCE.getRandom().nextBytes(ivBytes);
             ivSpec = new IvParameterSpec(ivBytes);
         }
         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount, ivSpec);
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBMAC1Core.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBMAC1Core.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -123,7 +123,7 @@
             // generate default for salt and iteration count if necessary
             if (salt == null) {
                 salt = new byte[DEFAULT_SALT_LENGTH];
-                SunJCE.RANDOM.nextBytes(salt);
+                SunJCE.getRandom().nextBytes(salt);
             }
             if (iCount == 0) iCount = DEFAULT_COUNT;
         } else if (!(params instanceof PBEParameterSpec)) {
--- a/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -227,7 +227,7 @@
             // follow the recommendation in PKCS12 v1.0
             // section B.4 to generate salt and iCount.
             salt = new byte[DEFAULT_SALT_LENGTH];
-            SunJCE.RANDOM.nextBytes(salt);
+            SunJCE.getRandom().nextBytes(salt);
             iCount = DEFAULT_COUNT;
         }
         PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount);
@@ -294,7 +294,7 @@
                 if (random != null) {
                     random.nextBytes(salt);
                 } else {
-                    SunJCE.RANDOM.nextBytes(salt);
+                    SunJCE.getRandom().nextBytes(salt);
                 }
             }
             if (iCount == 0) iCount = DEFAULT_COUNT;
--- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,7 @@
  * - ARCFOUR (RC4 compatible)
  *
  * - Cipher modes ECB, CBC, CFB, OFB, PCBC, CTR, and CTS for all block ciphers
+ *   and mode GCM for AES cipher
  *
  * - Cipher padding ISO10126Padding for non-PKCS#5 block ciphers and
  *   NoPadding and PKCS5Padding for all block ciphers
@@ -90,7 +91,12 @@
     /* Are we debugging? -- for developers */
     static final boolean debug = false;
 
-    static final SecureRandom RANDOM = new SecureRandom();
+    // lazy initialize SecureRandom to avoid potential recursion if Sun
+    // provider has not been installed yet
+    private static class SecureRandomHolder {
+        static final SecureRandom RANDOM = new SecureRandom();
+    }
+    static SecureRandom getRandom() { return SecureRandomHolder.RANDOM; }
 
     public SunJCE() {
         /* We are the "SunJCE" provider */
@@ -100,7 +106,7 @@
             "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
             "|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64";
         final String BLOCK_MODES128 = BLOCK_MODES +
-            "|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" +
+            "|GCM|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128" +
             "|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128";
         final String BLOCK_PADS = "NOPADDING|PKCS5PADDING|ISO10126PADDING";
 
@@ -258,6 +264,9 @@
                     put("Cipher.AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding");
                     put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
                     put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.4", "AES_128/CFB/NoPadding");
+                    put("Cipher.AES_128/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_GCM_NoPadding");
+                    put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding");
+                    put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.6", "AES_128/GCM/NoPadding");
 
                     put("Cipher.AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding");
                     put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.21", "AES_192/ECB/NoPadding");
@@ -271,7 +280,9 @@
                     put("Cipher.AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding");
                     put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
                     put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.24", "AES_192/CFB/NoPadding");
-
+                    put("Cipher.AES_192/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_GCM_NoPadding");
+                    put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding");
+                    put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.26", "AES_192/GCM/NoPadding");
 
                     put("Cipher.AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding");
                     put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.41", "AES_256/ECB/NoPadding");
@@ -285,6 +296,9 @@
                     put("Cipher.AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding");
                     put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
                     put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.44", "AES_256/CFB/NoPadding");
+                    put("Cipher.AES_256/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_GCM_NoPadding");
+                    put("Alg.Alias.Cipher.2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding");
+                    put("Alg.Alias.Cipher.OID.2.16.840.1.101.3.4.1.46", "AES_256/GCM/NoPadding");
 
                     put("Cipher.AESWrap", "com.sun.crypto.provider.AESWrapCipher$General");
                     put("Cipher.AESWrap SupportedModes", "ECB");
@@ -509,6 +523,8 @@
                     put("AlgorithmParameters.AES",
                         "com.sun.crypto.provider.AESParameters");
                     put("Alg.Alias.AlgorithmParameters.Rijndael", "AES");
+                    put("AlgorithmParameters.GCM",
+                        "com.sun.crypto.provider.GCMParameters");
 
 
                     put("AlgorithmParameters.RC2",
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java	Wed Jan 16 11:58:15 2013 -0800
@@ -860,9 +860,9 @@
      * @return     the specified subsequence.
      *
      * @throws  IndexOutOfBoundsException
-     *          if <tt>start</tt> or <tt>end</tt> are negative,
-     *          if <tt>end</tt> is greater than <tt>length()</tt>,
-     *          or if <tt>start</tt> is greater than <tt>end</tt>
+     *          if {@code start} or {@code end} are negative,
+     *          if {@code end} is greater than {@code length()},
+     *          or if {@code start} is greater than {@code end}
      * @spec JSR-51
      */
     @Override
@@ -1292,7 +1292,7 @@
     /**
      * Returns the index within this string of the first occurrence of the
      * specified substring, starting at the specified index.  The integer
-     * returned is the smallest value <tt>k</tt> for which:
+     * returned is the smallest value {@code k} for which:
      * <blockquote><pre>
      *     k >= Math.min(fromIndex, str.length()) &&
      *                   this.toString().startsWith(str, k)
@@ -1418,7 +1418,7 @@
     public abstract String toString();
 
     /**
-     * Needed by <tt>String</tt> for the contentEquals method.
+     * Needed by {@code String} for the contentEquals method.
      */
     final char[] getValue() {
         return value;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/FunctionalInterface.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates that an interface type declaration is intended to be a
+ * <i>functional interface</i> as defined by the Java Language
+ * Specification.
+ *
+ * Conceptually, a functional interface has exactly one abstract
+ * method.  Since {@linkplain java.lang.reflect.Method#isDefault()
+ * default methods} have an implementation, they are not abstract.  If
+ * an interface declares an abstract method overriding one of the
+ * public methods of {@code java.lang.Object}, that also does
+ * <em>not</em> count toward the interface's abstract method count
+ * since any implementation of the interface will have an
+ * implementation from {@code java.lang.Object} or elsewhere.
+ *
+ * <p>Note that instances of functional interfaces can be created with
+ * lambda expressions, method references, or constructor references.
+ *
+ * <p>If a type is annotated with this annotation type, compilers are
+ * required to generate an error message unless:
+ *
+ * <ul>
+ * <li> The type is an interface type and not an annotation type, enum, or class.
+ * <li> The annotated type satisfies the requirements of a functional interface.
+ * </ul>
+ *
+ * @jls 4.3.2. The Class Object
+ * @jls 9.8 Functional Interfaces
+ * @jls 9.4.3 Interface Method Body
+ * @since 1.8
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface FunctionalInterface {}
--- a/jdk/src/share/classes/java/lang/Integer.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/lang/Integer.java	Wed Jan 16 11:58:15 2013 -0800
@@ -772,7 +772,7 @@
                 int i = parseInt(integerCacheHighPropValue);
                 i = Math.max(i, 127);
                 // Maximum array size is Integer.MAX_VALUE
-                h = Math.min(i, Integer.MAX_VALUE - (-low));
+                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
             }
             high = h;
 
--- a/jdk/src/share/classes/java/lang/String.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/lang/String.java	Wed Jan 16 11:58:15 2013 -0800
@@ -615,10 +615,10 @@
     }
 
     /**
-     * Returns <tt>true</tt> if, and only if, {@link #length()} is <tt>0</tt>.
+     * Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
      *
-     * @return <tt>true</tt> if {@link #length()} is <tt>0</tt>, otherwise
-     * <tt>false</tt>
+     * @return {@code true} if {@link #length()} is {@code 0}, otherwise
+     * {@code false}
      *
      * @since 1.6
      */
@@ -1229,23 +1229,23 @@
     /**
      * Tests if two string regions are equal.
      * <p>
-     * A substring of this <tt>String</tt> object is compared to a substring
+     * A substring of this {@code String} object is compared to a substring
      * of the argument other. The result is true if these substrings
      * represent identical character sequences. The substring of this
-     * <tt>String</tt> object to be compared begins at index <tt>toffset</tt>
-     * and has length <tt>len</tt>. The substring of other to be compared
-     * begins at index <tt>ooffset</tt> and has length <tt>len</tt>. The
-     * result is <tt>false</tt> if and only if at least one of the following
+     * {@code String} object to be compared begins at index {@code toffset}
+     * and has length {@code len}. The substring of other to be compared
+     * begins at index {@code ooffset} and has length {@code len}. The
+     * result is {@code false} if and only if at least one of the following
      * is true:
-     * <ul><li><tt>toffset</tt> is negative.
-     * <li><tt>ooffset</tt> is negative.
-     * <li><tt>toffset+len</tt> is greater than the length of this
-     * <tt>String</tt> object.
-     * <li><tt>ooffset+len</tt> is greater than the length of the other
+     * <ul><li>{@code toffset} is negative.
+     * <li>{@code ooffset} is negative.
+     * <li>{@code toffset+len} is greater than the length of this
+     * {@code String} object.
+     * <li>{@code ooffset+len} is greater than the length of the other
      * argument.
-     * <li>There is some nonnegative integer <i>k</i> less than <tt>len</tt>
+     * <li>There is some nonnegative integer <i>k</i> less than {@code len}
      * such that:
-     * <tt>this.charAt(toffset+<i>k</i>)&nbsp;!=&nbsp;other.charAt(ooffset+<i>k</i>)</tt>
+     * <code>this.charAt(toffset+<i>k</i>)&nbsp;!=&nbsp;other.charAt(ooffset+<i>k</i>)</code>
      * </ul>
      *
      * @param   toffset   the starting offset of the subregion in this string.
@@ -1280,28 +1280,28 @@
     /**
      * Tests if two string regions are equal.
      * <p>
-     * A substring of this <tt>String</tt> object is compared to a substring
-     * of the argument <tt>other</tt>. The result is <tt>true</tt> if these
+     * A substring of this {@code String} object is compared to a substring
+     * of the argument {@code other}. The result is {@code true} if these
      * substrings represent character sequences that are the same, ignoring
-     * case if and only if <tt>ignoreCase</tt> is true. The substring of
-     * this <tt>String</tt> object to be compared begins at index
-     * <tt>toffset</tt> and has length <tt>len</tt>. The substring of
-     * <tt>other</tt> to be compared begins at index <tt>ooffset</tt> and
-     * has length <tt>len</tt>. The result is <tt>false</tt> if and only if
+     * case if and only if {@code ignoreCase} is true. The substring of
+     * this {@code String} object to be compared begins at index
+     * {@code toffset} and has length {@code len}. The substring of
+     * {@code other} to be compared begins at index {@code ooffset} and
+     * has length {@code len}. The result is {@code false} if and only if
      * at least one of the following is true:
-     * <ul><li><tt>toffset</tt> is negative.
-     * <li><tt>ooffset</tt> is negative.
-     * <li><tt>toffset+len</tt> is greater than the length of this
-     * <tt>String</tt> object.
-     * <li><tt>ooffset+len</tt> is greater than the length of the other
+     * <ul><li>{@code toffset} is negative.
+     * <li>{@code ooffset} is negative.
+     * <li>{@code toffset+len} is greater than the length of this
+     * {@code String} object.
+     * <li>{@code ooffset+len} is greater than the length of the other
      * argument.
-     * <li><tt>ignoreCase</tt> is <tt>false</tt> and there is some nonnegative
-     * integer <i>k</i> less than <tt>len</tt> such that:
+     * <li>{@code ignoreCase} is {@code false} and there is some nonnegative
+     * integer <i>k</i> less than {@code len} such that:
      * <blockquote><pre>
      * this.charAt(toffset+k) != other.charAt(ooffset+k)
      * </pre></blockquote>
-     * <li><tt>ignoreCase</tt> is <tt>true</tt> and there is some nonnegative
-     * integer <i>k</i> less than <tt>len</tt> such that:
+     * <li>{@code ignoreCase} is {@code true} and there is some nonnegative
+     * integer <i>k</i> less than {@code len} such that:
      * <blockquote><pre>
      * Character.toLowerCase(this.charAt(toffset+k)) !=
      Character.toLowerCase(other.charAt(ooffset+k))
@@ -1500,12 +1500,12 @@
      * of {@code ch} in the range from 0 to 0xFFFF (inclusive),
      * this is the smallest value <i>k</i> such that:
      * <blockquote><pre>
-     * (this.charAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex)
+     * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
      * </pre></blockquote>
      * is true. For other values of {@code ch}, it is the
      * smallest value <i>k</i> such that:
      * <blockquote><pre>
-     * (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &gt;= fromIndex)
+     * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &gt;= fromIndex)
      * </pre></blockquote>
      * is true. In either case, if no such character occurs in this
      * string at or after position {@code fromIndex}, then
@@ -1604,12 +1604,12 @@
      * from 0 to 0xFFFF (inclusive), the index returned is the largest
      * value <i>k</i> such that:
      * <blockquote><pre>
-     * (this.charAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex)
+     * (this.charAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
      * </pre></blockquote>
      * is true. For other values of {@code ch}, it is the
      * largest value <i>k</i> such that:
      * <blockquote><pre>
-     * (this.codePointAt(<i>k</i>) == ch) && (<i>k</i> &lt;= fromIndex)
+     * (this.codePointAt(<i>k</i>) == ch) {@code &&} (<i>k</i> &lt;= fromIndex)
      * </pre></blockquote>
      * is true. In either case, if no such character occurs in this
      * string at or before position {@code fromIndex}, then
@@ -1690,7 +1690,7 @@
      *
      * <p>The returned index is the smallest value <i>k</i> for which:
      * <blockquote><pre>
-     * <i>k</i> &gt;= fromIndex && this.startsWith(str, <i>k</i>)
+     * <i>k</i> &gt;= fromIndex {@code &&} this.startsWith(str, <i>k</i>)
      * </pre></blockquote>
      * If no such value of <i>k</i> exists, then {@code -1} is returned.
      *
@@ -1799,7 +1799,7 @@
      *
      * <p>The returned index is the largest value <i>k</i> for which:
      * <blockquote><pre>
-     * <i>k</i> &lt;= fromIndex && this.startsWith(str, <i>k</i>)
+     * <i>k</i> {@code <=} fromIndex {@code &&} this.startsWith(str, <i>k</i>)
      * </pre></blockquote>
      * If no such value of <i>k</i> exists, then {@code -1} is returned.
      *
@@ -2080,17 +2080,18 @@
      * href="../util/regex/Pattern.html#sum">regular expression</a>.
      *
      * <p> An invocation of this method of the form
-     * <i>str</i><tt>.matches(</tt><i>regex</i><tt>)</tt> yields exactly the
+     * <i>str</i>{@code .matches(}<i>regex</i>{@code )} yields exactly the
      * same result as the expression
      *
-     * <blockquote><tt> {@link java.util.regex.Pattern}.{@link
-     * java.util.regex.Pattern#matches(String,CharSequence)
-     * matches}(</tt><i>regex</i><tt>,</tt> <i>str</i><tt>)</tt></blockquote>
+     * <blockquote>
+     * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#matches(String,CharSequence)
+     * matches(<i>regex</i>, <i>str</i>)}
+     * </blockquote>
      *
      * @param   regex
      *          the regular expression to which this string is to be matched
      *
-     * @return  <tt>true</tt> if, and only if, this string matches the
+     * @return  {@code true} if, and only if, this string matches the
      *          given regular expression
      *
      * @throws  PatternSyntaxException
@@ -2124,18 +2125,20 @@
      * given replacement.
      *
      * <p> An invocation of this method of the form
-     * <i>str</i><tt>.replaceFirst(</tt><i>regex</i><tt>,</tt> <i>repl</i><tt>)</tt>
+     * <i>str</i>{@code .replaceFirst(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
      * yields exactly the same result as the expression
      *
-     * <blockquote><tt>
-     * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
-     * compile}(</tt><i>regex</i><tt>).{@link
-     * java.util.regex.Pattern#matcher(java.lang.CharSequence)
-     * matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceFirst
-     * replaceFirst}(</tt><i>repl</i><tt>)</tt></blockquote>
+     * <blockquote>
+     * <code>
+     * {@link java.util.regex.Pattern}.{@link
+     * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+     * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
+     * java.util.regex.Matcher#replaceFirst replaceFirst}(<i>repl</i>)
+     * </code>
+     * </blockquote>
      *
      *<p>
-     * Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in the
+     * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
      * replacement string may cause the results to be different than if it were
      * being treated as a literal replacement string; see
      * {@link java.util.regex.Matcher#replaceFirst}.
@@ -2147,7 +2150,7 @@
      * @param   replacement
      *          the string to be substituted for the first match
      *
-     * @return  The resulting <tt>String</tt>
+     * @return  The resulting {@code String}
      *
      * @throws  PatternSyntaxException
      *          if the regular expression's syntax is invalid
@@ -2167,18 +2170,20 @@
      * given replacement.
      *
      * <p> An invocation of this method of the form
-     * <i>str</i><tt>.replaceAll(</tt><i>regex</i><tt>,</tt> <i>repl</i><tt>)</tt>
+     * <i>str</i>{@code .replaceAll(}<i>regex</i>{@code ,} <i>repl</i>{@code )}
      * yields exactly the same result as the expression
      *
-     * <blockquote><tt>
-     * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
-     * compile}(</tt><i>regex</i><tt>).{@link
-     * java.util.regex.Pattern#matcher(java.lang.CharSequence)
-     * matcher}(</tt><i>str</i><tt>).{@link java.util.regex.Matcher#replaceAll
-     * replaceAll}(</tt><i>repl</i><tt>)</tt></blockquote>
+     * <blockquote>
+     * <code>
+     * {@link java.util.regex.Pattern}.{@link
+     * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+     * java.util.regex.Pattern#matcher(java.lang.CharSequence) matcher}(<i>str</i>).{@link
+     * java.util.regex.Matcher#replaceAll replaceAll}(<i>repl</i>)
+     * </code>
+     * </blockquote>
      *
      *<p>
-     * Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in the
+     * Note that backslashes ({@code \}) and dollar signs ({@code $}) in the
      * replacement string may cause the results to be different than if it were
      * being treated as a literal replacement string; see
      * {@link java.util.regex.Matcher#replaceAll Matcher.replaceAll}.
@@ -2190,7 +2195,7 @@
      * @param   replacement
      *          the string to be substituted for each match
      *
-     * @return  The resulting <tt>String</tt>
+     * @return  The resulting {@code String}
      *
      * @throws  PatternSyntaxException
      *          if the regular expression's syntax is invalid
@@ -2234,7 +2239,7 @@
      * expression does not match any part of the input then the resulting array
      * has just one element, namely this string.
      *
-     * <p> The <tt>limit</tt> parameter controls the number of times the
+     * <p> The {@code limit} parameter controls the number of times the
      * pattern is applied and therefore affects the length of the resulting
      * array.  If the limit <i>n</i> is greater than zero then the pattern
      * will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's
@@ -2245,7 +2250,7 @@
      * the pattern will be applied as many times as possible, the array can
      * have any length, and trailing empty strings will be discarded.
      *
-     * <p> The string <tt>"boo:and:foo"</tt>, for example, yields the
+     * <p> The string {@code "boo:and:foo"}, for example, yields the
      * following results with these parameters:
      *
      * <blockquote><table cellpadding=1 cellspacing=0 summary="Split example showing regex, limit, and result">
@@ -2256,33 +2261,34 @@
      * </tr>
      * <tr><td align=center>:</td>
      *     <td align=center>2</td>
-     *     <td><tt>{ "boo", "and:foo" }</tt></td></tr>
+     *     <td>{@code { "boo", "and:foo" }}</td></tr>
      * <tr><td align=center>:</td>
      *     <td align=center>5</td>
-     *     <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
+     *     <td>{@code { "boo", "and", "foo" }}</td></tr>
      * <tr><td align=center>:</td>
      *     <td align=center>-2</td>
-     *     <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
+     *     <td>{@code { "boo", "and", "foo" }}</td></tr>
      * <tr><td align=center>o</td>
      *     <td align=center>5</td>
-     *     <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
+     *     <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
      * <tr><td align=center>o</td>
      *     <td align=center>-2</td>
-     *     <td><tt>{ "b", "", ":and:f", "", "" }</tt></td></tr>
+     *     <td>{@code { "b", "", ":and:f", "", "" }}</td></tr>
      * <tr><td align=center>o</td>
      *     <td align=center>0</td>
-     *     <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
+     *     <td>{@code { "b", "", ":and:f" }}</td></tr>
      * </table></blockquote>
      *
      * <p> An invocation of this method of the form
-     * <i>str.</i><tt>split(</tt><i>regex</i><tt>,</tt>&nbsp;<i>n</i><tt>)</tt>
+     * <i>str.</i>{@code split(}<i>regex</i>{@code ,}&nbsp;<i>n</i>{@code )}
      * yields the same result as the expression
      *
      * <blockquote>
-     * {@link java.util.regex.Pattern}.{@link java.util.regex.Pattern#compile
-     * compile}<tt>(</tt><i>regex</i><tt>)</tt>.{@link
-     * java.util.regex.Pattern#split(java.lang.CharSequence,int)
-     * split}<tt>(</tt><i>str</i><tt>,</tt>&nbsp;<i>n</i><tt>)</tt>
+     * <code>
+     * {@link java.util.regex.Pattern}.{@link
+     * java.util.regex.Pattern#compile compile}(<i>regex</i>).{@link
+     * java.util.regex.Pattern#split(java.lang.CharSequence,int) split}(<i>str</i>,&nbsp;<i>n</i>)
+     * </code>
      * </blockquote>
      *
      *
@@ -2364,7 +2370,7 @@
      * argument of zero.  Trailing empty strings are therefore not included in
      * the resulting array.
      *
-     * <p> The string <tt>"boo:and:foo"</tt>, for example, yields the following
+     * <p> The string {@code "boo:and:foo"}, for example, yields the following
      * results with these expressions:
      *
      * <blockquote><table cellpadding=1 cellspacing=0 summary="Split examples showing regex and result">
@@ -2373,9 +2379,9 @@
      *  <th>Result</th>
      * </tr>
      * <tr><td align=center>:</td>
-     *     <td><tt>{ "boo", "and", "foo" }</tt></td></tr>
+     *     <td>{@code { "boo", "and", "foo" }}</td></tr>
      * <tr><td align=center>o</td>
-     *     <td><tt>{ "b", "", ":and:f" }</tt></td></tr>
+     *     <td>{@code { "b", "", ":and:f" }}</td></tr>
      * </table></blockquote>
      *
      *
@@ -2815,7 +2821,7 @@
      *         limited by the maximum dimension of a Java array as defined by
      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
      *         The behaviour on a
-     *         <tt>null</tt> argument depends on the <a
+     *         {@code null} argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
      * @throws  java.util.IllegalFormatException
@@ -2828,7 +2834,7 @@
      *          formatter class specification.
      *
      * @throws  NullPointerException
-     *          If the <tt>format</tt> is <tt>null</tt>
+     *          If the {@code format} is {@code null}
      *
      * @return  A formatted string
      *
@@ -2845,7 +2851,7 @@
      *
      * @param  l
      *         The {@linkplain java.util.Locale locale} to apply during
-     *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
+     *         formatting.  If {@code l} is {@code null} then no localization
      *         is applied.
      *
      * @param  format
@@ -2859,7 +2865,7 @@
      *         limited by the maximum dimension of a Java array as defined by
      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
      *         The behaviour on a
-     *         <tt>null</tt> argument depends on the <a
+     *         {@code null} argument depends on the <a
      *         href="../util/Formatter.html#syntax">conversion</a>.
      *
      * @throws  java.util.IllegalFormatException
@@ -2872,7 +2878,7 @@
      *          formatter class specification
      *
      * @throws  NullPointerException
-     *          If the <tt>format</tt> is <tt>null</tt>
+     *          If the {@code format} is {@code null}
      *
      * @return  A formatted string
      *
@@ -3143,7 +3149,7 @@
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>
-    * <p/>
+    * </p>
      * The hash value will never be zero.
     *
     * @return  a hash code value for this object.
--- a/jdk/src/share/classes/java/lang/StringBuffer.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/lang/StringBuffer.java	Wed Jan 16 11:58:15 2013 -0800
@@ -57,7 +57,7 @@
  * <p>
  * In general, if sb refers to an instance of a {@code StringBuffer},
  * then {@code sb.append(x)} has the same effect as
- * {@code sb.insert(sb.length(),&nbsp;x)}.
+ * {@code sb.insert(sb.length(), x)}.
  * <p>
  * Whenever an operation occurs involving a source sequence (such as
  * appending or inserting from a source sequence), this class synchronizes
@@ -80,7 +80,7 @@
  *
  * As of  release JDK 5, this class has been supplemented with an equivalent
  * class designed for use by a single thread, {@link StringBuilder}.  The
- * <tt>StringBuilder</tt> class should generally be used in preference to
+ * {@code StringBuilder} class should generally be used in preference to
  * this one, as it supports all of the same operations but it is faster, as
  * it performs no synchronization.
  *
@@ -262,17 +262,17 @@
     }
 
     /**
-     * Appends the specified <tt>StringBuffer</tt> to this sequence.
+     * Appends the specified {@code StringBuffer} to this sequence.
      * <p>
-     * The characters of the <tt>StringBuffer</tt> argument are appended,
-     * in order, to the contents of this <tt>StringBuffer</tt>, increasing the
-     * length of this <tt>StringBuffer</tt> by the length of the argument.
-     * If <tt>sb</tt> is <tt>null</tt>, then the four characters
-     * <tt>"null"</tt> are appended to this <tt>StringBuffer</tt>.
+     * The characters of the {@code StringBuffer} argument are appended,
+     * in order, to the contents of this {@code StringBuffer}, increasing the
+     * length of this {@code StringBuffer} by the length of the argument.
+     * If {@code sb} is {@code null}, then the four characters
+     * {@code "null"} are appended to this {@code StringBuffer}.
      * <p>
      * Let <i>n</i> be the length of the old character sequence, the one
-     * contained in the <tt>StringBuffer</tt> just prior to execution of the
-     * <tt>append</tt> method. Then the character at index <i>k</i> in
+     * contained in the {@code StringBuffer} just prior to execution of the
+     * {@code append} method. Then the character at index <i>k</i> in
      * the new character sequence is equal to the character at index <i>k</i>
      * in the old character sequence, if <i>k</i> is less than <i>n</i>;
      * otherwise, it is equal to the character at index <i>k-n</i> in the
@@ -281,7 +281,7 @@
      * This method synchronizes on {@code this}, the destination
      * object, but does not synchronize on the source ({@code sb}).
      *
-     * @param   sb   the <tt>StringBuffer</tt> to append.
+     * @param   sb   the {@code StringBuffer} to append.
      * @return  a reference to this object.
      * @since 1.4
      */
--- a/jdk/src/share/classes/java/lang/StringBuilder.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/lang/StringBuilder.java	Wed Jan 16 11:58:15 2013 -0800
@@ -28,39 +28,39 @@
 
 /**
  * A mutable sequence of characters.  This class provides an API compatible
- * with <code>StringBuffer</code>, but with no guarantee of synchronization.
+ * with {@code StringBuffer}, but with no guarantee of synchronization.
  * This class is designed for use as a drop-in replacement for
- * <code>StringBuffer</code> in places where the string buffer was being
+ * {@code StringBuffer} in places where the string buffer was being
  * used by a single thread (as is generally the case).   Where possible,
  * it is recommended that this class be used in preference to
- * <code>StringBuffer</code> as it will be faster under most implementations.
+ * {@code StringBuffer} as it will be faster under most implementations.
  *
- * <p>The principal operations on a <code>StringBuilder</code> are the
- * <code>append</code> and <code>insert</code> methods, which are
+ * <p>The principal operations on a {@code StringBuilder} are the
+ * {@code append} and {@code insert} methods, which are
  * overloaded so as to accept data of any type. Each effectively
  * converts a given datum to a string and then appends or inserts the
  * characters of that string to the string builder. The
- * <code>append</code> method always adds these characters at the end
- * of the builder; the <code>insert</code> method adds the characters at
+ * {@code append} method always adds these characters at the end
+ * of the builder; the {@code insert} method adds the characters at
  * a specified point.
  * <p>
- * For example, if <code>z</code> refers to a string builder object
- * whose current contents are "<code>start</code>", then
- * the method call <code>z.append("le")</code> would cause the string
- * builder to contain "<code>startle</code>", whereas
- * <code>z.insert(4, "le")</code> would alter the string builder to
- * contain "<code>starlet</code>".
+ * For example, if {@code z} refers to a string builder object
+ * whose current contents are "{@code start}", then
+ * the method call {@code z.append("le")} would cause the string
+ * builder to contain "{@code startle}", whereas
+ * {@code z.insert(4, "le")} would alter the string builder to
+ * contain "{@code starlet}".
  * <p>
- * In general, if sb refers to an instance of a <code>StringBuilder</code>,
- * then <code>sb.append(x)</code> has the same effect as
- * <code>sb.insert(sb.length(),&nbsp;x)</code>.
- *
+ * In general, if sb refers to an instance of a {@code StringBuilder},
+ * then {@code sb.append(x)} has the same effect as
+ * {@code sb.insert(sb.length(), x)}.
+ * <p>
  * Every string builder has a capacity. As long as the length of the
  * character sequence contained in the string builder does not exceed
  * the capacity, it is not necessary to allocate a new internal
  * buffer. If the internal buffer overflows, it is automatically made larger.
  *
- * <p>Instances of <code>StringBuilder</code> are not safe for
+ * <p>Instances of {@code StringBuilder} are not safe for
  * use by multiple threads. If such synchronization is required then it is
  * recommended that {@link java.lang.StringBuffer} be used.
  *
@@ -87,11 +87,11 @@
 
     /**
      * Constructs a string builder with no characters in it and an
-     * initial capacity specified by the <code>capacity</code> argument.
+     * initial capacity specified by the {@code capacity} argument.
      *
      * @param      capacity  the initial capacity.
-     * @throws     NegativeArraySizeException  if the <code>capacity</code>
-     *               argument is less than <code>0</code>.
+     * @throws     NegativeArraySizeException  if the {@code capacity}
+     *               argument is less than {@code 0}.
      */
     public StringBuilder(int capacity) {
         super(capacity);
@@ -100,10 +100,10 @@
     /**
      * Constructs a string builder initialized to the contents of the
      * specified string. The initial capacity of the string builder is
-     * <code>16</code> plus the length of the string argument.
+     * {@code 16} plus the length of the string argument.
      *
      * @param   str   the initial contents of the buffer.
-     * @throws    NullPointerException if <code>str</code> is <code>null</code>
+     * @throws    NullPointerException if {@code str} is {@code null}
      */
     public StringBuilder(String str) {
         super(str.length() + 16);
@@ -112,12 +112,12 @@
 
     /**
      * Constructs a string builder that contains the same characters
-     * as the specified <code>CharSequence</code>. The initial capacity of
-     * the string builder is <code>16</code> plus the length of the
-     * <code>CharSequence</code> argument.
+     * as the specified {@code CharSequence}. The initial capacity of
+     * the string builder is {@code 16} plus the length of the
+     * {@code CharSequence} argument.
      *
      * @param      seq   the sequence to copy.
-     * @throws    NullPointerException if <code>seq</code> is <code>null</code>
+     * @throws    NullPointerException if {@code seq} is {@code null}
      */
     public StringBuilder(CharSequence seq) {
         this(seq.length() + 16);
@@ -136,22 +136,22 @@
     }
 
     /**
-     * Appends the specified <tt>StringBuffer</tt> to this sequence.
+     * Appends the specified {@code StringBuffer} to this sequence.
      * <p>
-     * The characters of the <tt>StringBuffer</tt> argument are appended,
+     * The characters of the {@code StringBuffer} argument are appended,
      * in order, to this sequence, increasing the
      * length of this sequence by the length of the argument.
-     * If <tt>sb</tt> is <tt>null</tt>, then the four characters
-     * <tt>"null"</tt> are appended to this sequence.
+     * If {@code sb} is {@code null}, then the four characters
+     * {@code "null"} are appended to this sequence.
      * <p>
      * Let <i>n</i> be the length of this character sequence just prior to
-     * execution of the <tt>append</tt> method. Then the character at index
+     * execution of the {@code append} method. Then the character at index
      * <i>k</i> in the new character sequence is equal to the character at
      * index <i>k</i> in the old character sequence, if <i>k</i> is less than
      * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
-     * in the argument <code>sb</code>.
+     * in the argument {@code sb}.
      *
-     * @param   sb   the <tt>StringBuffer</tt> to append.
+     * @param   sb   the {@code StringBuffer} to append.
      * @return  a reference to this object.
      */
     public StringBuilder append(StringBuffer sb) {
@@ -418,13 +418,13 @@
     }
 
     /**
-     * Save the state of the <tt>StringBuilder</tt> instance to a stream
+     * Save the state of the {@code StringBuilder} instance to a stream
      * (that is, serialize it).
      *
      * @serialData the number of characters currently stored in the string
-     *             builder (<tt>int</tt>), followed by the characters in the
-     *             string builder (<tt>char[]</tt>).   The length of the
-     *             <tt>char</tt> array may be greater than the number of
+     *             builder ({@code int}), followed by the characters in the
+     *             string builder ({@code char[]}).   The length of the
+     *             {@code char} array may be greater than the number of
      *             characters currently stored in the string builder, in which
      *             case extra characters are ignored.
      */
--- a/jdk/src/share/classes/java/lang/StringIndexOutOfBoundsException.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/lang/StringIndexOutOfBoundsException.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 package java.lang;
 
 /**
- * Thrown by <code>String</code> methods to indicate that an index
+ * Thrown by {@code String} methods to indicate that an index
  * is either negative or greater than the size of the string.  For
  * some methods such as the charAt method, this exception also is
  * thrown when the index is equal to the size of the string.
@@ -40,7 +40,7 @@
     private static final long serialVersionUID = -6762910422159637258L;
 
     /**
-     * Constructs a <code>StringIndexOutOfBoundsException</code> with no
+     * Constructs a {@code StringIndexOutOfBoundsException} with no
      * detail message.
      *
      * @since   JDK1.0.
@@ -50,7 +50,7 @@
     }
 
     /**
-     * Constructs a <code>StringIndexOutOfBoundsException</code> with
+     * Constructs a {@code StringIndexOutOfBoundsException} with
      * the specified detail message.
      *
      * @param   s   the detail message.
@@ -60,7 +60,7 @@
     }
 
     /**
-     * Constructs a new <code>StringIndexOutOfBoundsException</code>
+     * Constructs a new {@code StringIndexOutOfBoundsException}
      * class with an argument indicating the illegal index.
      *
      * @param   index   the illegal index.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/lang/annotation/Repeatable.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.annotation;
+
+/**
+ * The annotation type {@code java.lang.annotation.Repeatable} is
+ * used to indicate that the annotation type whose declaration it
+ * (meta-)annotates is <em>repeatable</em>. The value of
+ * {@code @Repeatable} indicates the <em>containing annotation
+ * type</em> for the repeatable annotation type.
+ *
+ * @since 1.8
+ * @jls 9.6 Annotation Types
+ * @jls 9.7 Annotations
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface Repeatable {
+    /**
+     * Indicates the <em>containing annotation type</em> for the
+     * repeatable annotation type.
+     */
+    Class<? extends Annotation> value();
+}
--- a/jdk/src/share/classes/java/security/Principal.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/security/Principal.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 
 package java.security;
 
+import javax.security.auth.Subject;
+
 /**
  * This interface represents the abstract notion of a principal, which
  * can be used to represent any entity, such as an individual, a
@@ -45,7 +47,6 @@
      *
      * @return true if the principal passed in is the same as that
      * encapsulated by this principal, and false otherwise.
-
      */
     public boolean equals(Object another);
 
@@ -69,4 +70,24 @@
      * @return the name of this principal.
      */
     public String getName();
+
+    /**
+     * Returns true if the specified subject is implied by this principal.
+     *
+     * <p>The default implementation of this method returns true if
+     * {@code subject} is non-null and contains at least one principal that
+     * is equal to this principal.
+     *
+     * <p>Subclasses may override this with a different implementation, if
+     * necessary.
+     *
+     * @return true if {@code subject} is non-null and is
+     *              implied by this principal, or false otherwise.
+     * @since 1.8
+     */
+    public default boolean implies(Subject subject) {
+        if (subject == null)
+            return false;
+        return subject.getPrincipals().contains(this);
+    }
 }
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java	Wed Jan 16 11:58:15 2013 -0800
@@ -2611,6 +2611,7 @@
      * {@link #shutdown} or {@link #shutdownNow}.
      *
      * @return the common pool instance
+     * @since 1.8
      */
     public static ForkJoinPool commonPool() {
         // assert commonPool != null : "static init error";
@@ -2793,6 +2794,7 @@
      * Returns the targeted parallelism level of the common pool.
      *
      * @return the targeted parallelism level of the common pool
+     * @since 1.8
      */
     public static int getCommonPoolParallelism() {
         return commonPoolParallelism;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicBoolean.java	Wed Jan 16 11:58:15 2013 -0800
@@ -111,7 +111,7 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public boolean weakCompareAndSet(boolean expect, boolean update) {
         int e = expect ? 1 : 0;
@@ -146,16 +146,16 @@
      * @return the previous value
      */
     public final boolean getAndSet(boolean newValue) {
-        for (;;) {
-            boolean current = get();
-            if (compareAndSet(current, newValue))
-                return current;
-        }
+        boolean prev;
+        do {
+            prev = get();
+        } while (!compareAndSet(prev, newValue));
+        return prev;
     }
 
     /**
      * Returns the String representation of the current value.
-     * @return the String representation of the current value.
+     * @return the String representation of the current value
      */
     public String toString() {
         return Boolean.toString(get());
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicInteger.java	Wed Jan 16 11:58:15 2013 -0800
@@ -115,11 +115,7 @@
      * @return the previous value
      */
     public final int getAndSet(int newValue) {
-        for (;;) {
-            int current = get();
-            if (compareAndSet(current, newValue))
-                return current;
-        }
+        return unsafe.getAndSetInt(this, valueOffset, newValue);
     }
 
     /**
@@ -145,7 +141,7 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public final boolean weakCompareAndSet(int expect, int update) {
         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
@@ -157,12 +153,7 @@
      * @return the previous value
      */
     public final int getAndIncrement() {
-        for (;;) {
-            int current = get();
-            int next = current + 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return getAndAdd(1);
     }
 
     /**
@@ -171,12 +162,7 @@
      * @return the previous value
      */
     public final int getAndDecrement() {
-        for (;;) {
-            int current = get();
-            int next = current - 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return getAndAdd(-1);
     }
 
     /**
@@ -186,12 +172,7 @@
      * @return the previous value
      */
     public final int getAndAdd(int delta) {
-        for (;;) {
-            int current = get();
-            int next = current + delta;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return unsafe.getAndAddInt(this, valueOffset, delta);
     }
 
     /**
@@ -200,12 +181,7 @@
      * @return the updated value
      */
     public final int incrementAndGet() {
-        for (;;) {
-            int current = get();
-            int next = current + 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return getAndAdd(1) + 1;
     }
 
     /**
@@ -214,12 +190,7 @@
      * @return the updated value
      */
     public final int decrementAndGet() {
-        for (;;) {
-            int current = get();
-            int next = current - 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return getAndAdd(-1) - 1;
     }
 
     /**
@@ -229,17 +200,12 @@
      * @return the updated value
      */
     public final int addAndGet(int delta) {
-        for (;;) {
-            int current = get();
-            int next = current + delta;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return getAndAdd(delta) + delta;
     }
 
     /**
      * Returns the String representation of the current value.
-     * @return the String representation of the current value.
+     * @return the String representation of the current value
      */
     public String toString() {
         return Integer.toString(get());
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java	Wed Jan 16 11:58:15 2013 -0800
@@ -145,12 +145,7 @@
      * @return the previous value
      */
     public final int getAndSet(int i, int newValue) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            int current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, newValue))
-                return current;
-        }
+        return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -182,7 +177,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public final boolean weakCompareAndSet(int i, int expect, int update) {
         return compareAndSet(i, expect, update);
@@ -216,12 +211,7 @@
      * @return the previous value
      */
     public final int getAndAdd(int i, int delta) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            int current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, current + delta))
-                return current;
-        }
+        return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);
     }
 
     /**
@@ -231,7 +221,7 @@
      * @return the updated value
      */
     public final int incrementAndGet(int i) {
-        return addAndGet(i, 1);
+        return getAndAdd(i, 1) + 1;
     }
 
     /**
@@ -241,7 +231,7 @@
      * @return the updated value
      */
     public final int decrementAndGet(int i) {
-        return addAndGet(i, -1);
+        return getAndAdd(i, -1) - 1;
     }
 
     /**
@@ -252,13 +242,7 @@
      * @return the updated value
      */
     public final int addAndGet(int i, int delta) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            int current = getRaw(offset);
-            int next = current + delta;
-            if (compareAndSetRaw(offset, current, next))
-                return next;
-        }
+        return getAndAdd(i, delta) + delta;
     }
 
     /**
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java	Wed Jan 16 11:58:15 2013 -0800
@@ -159,11 +159,11 @@
      * @return the previous value
      */
     public int getAndSet(T obj, int newValue) {
-        for (;;) {
-            int current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
-        }
+        int prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
     }
 
     /**
@@ -174,12 +174,12 @@
      * @return the previous value
      */
     public int getAndIncrement(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -190,12 +190,12 @@
      * @return the previous value
      */
     public int getAndDecrement(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -207,12 +207,12 @@
      * @return the previous value
      */
     public int getAndAdd(T obj, int delta) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -223,12 +223,12 @@
      * @return the updated value
      */
     public int incrementAndGet(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -239,12 +239,12 @@
      * @return the updated value
      */
     public int decrementAndGet(T obj) {
-        for (;;) {
-            int current = get(obj);
-            int next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -256,12 +256,12 @@
      * @return the updated value
      */
     public int addAndGet(T obj, int delta) {
-        for (;;) {
-            int current = get(obj);
-            int next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        int prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -361,6 +361,36 @@
             return unsafe.getIntVolatile(obj, offset);
         }
 
+        public int getAndSet(T obj, int newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            return unsafe.getAndSetInt(obj, offset, newValue);
+        }
+
+        public int getAndIncrement(T obj) {
+            return getAndAdd(obj, 1);
+        }
+
+        public int getAndDecrement(T obj) {
+            return getAndAdd(obj, -1);
+        }
+
+        public int getAndAdd(T obj, int delta) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            return unsafe.getAndAddInt(obj, offset, delta);
+        }
+
+        public int incrementAndGet(T obj) {
+            return getAndAdd(obj, 1) + 1;
+        }
+
+        public int decrementAndGet(T obj) {
+             return getAndAdd(obj, -1) - 1;
+        }
+
+        public int addAndGet(T obj, int delta) {
+            return getAndAdd(obj, delta) + delta;
+        }
+
         private void ensureProtectedAccess(T obj) {
             if (cclass.isInstance(obj)) {
                 return;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLong.java	Wed Jan 16 11:58:15 2013 -0800
@@ -129,11 +129,7 @@
      * @return the previous value
      */
     public final long getAndSet(long newValue) {
-        while (true) {
-            long current = get();
-            if (compareAndSet(current, newValue))
-                return current;
-        }
+        return unsafe.getAndSetLong(this, valueOffset, newValue);
     }
 
     /**
@@ -159,7 +155,7 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public final boolean weakCompareAndSet(long expect, long update) {
         return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
@@ -171,12 +167,7 @@
      * @return the previous value
      */
     public final long getAndIncrement() {
-        while (true) {
-            long current = get();
-            long next = current + 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return getAndAdd(1);
     }
 
     /**
@@ -185,12 +176,7 @@
      * @return the previous value
      */
     public final long getAndDecrement() {
-        while (true) {
-            long current = get();
-            long next = current - 1;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return getAndAdd(-1);
     }
 
     /**
@@ -200,12 +186,7 @@
      * @return the previous value
      */
     public final long getAndAdd(long delta) {
-        while (true) {
-            long current = get();
-            long next = current + delta;
-            if (compareAndSet(current, next))
-                return current;
-        }
+        return unsafe.getAndAddLong(this, valueOffset, delta);
     }
 
     /**
@@ -214,12 +195,7 @@
      * @return the updated value
      */
     public final long incrementAndGet() {
-        for (;;) {
-            long current = get();
-            long next = current + 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return getAndAdd(1) + 1;
     }
 
     /**
@@ -228,12 +204,7 @@
      * @return the updated value
      */
     public final long decrementAndGet() {
-        for (;;) {
-            long current = get();
-            long next = current - 1;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return getAndAdd(-1) - 1;
     }
 
     /**
@@ -243,17 +214,12 @@
      * @return the updated value
      */
     public final long addAndGet(long delta) {
-        for (;;) {
-            long current = get();
-            long next = current + delta;
-            if (compareAndSet(current, next))
-                return next;
-        }
+        return getAndAdd(delta) + delta;
     }
 
     /**
      * Returns the String representation of the current value.
-     * @return the String representation of the current value.
+     * @return the String representation of the current value
      */
     public String toString() {
         return Long.toString(get());
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongArray.java	Wed Jan 16 11:58:15 2013 -0800
@@ -144,12 +144,7 @@
      * @return the previous value
      */
     public final long getAndSet(int i, long newValue) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            long current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, newValue))
-                return current;
-        }
+        return unsafe.getAndSetLong(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -181,7 +176,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public final boolean weakCompareAndSet(int i, long expect, long update) {
         return compareAndSet(i, expect, update);
@@ -215,12 +210,7 @@
      * @return the previous value
      */
     public final long getAndAdd(int i, long delta) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            long current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, current + delta))
-                return current;
-        }
+        return unsafe.getAndAddLong(array, checkedByteOffset(i), delta);
     }
 
     /**
@@ -230,7 +220,7 @@
      * @return the updated value
      */
     public final long incrementAndGet(int i) {
-        return addAndGet(i, 1);
+        return getAndAdd(i, 1) + 1;
     }
 
     /**
@@ -240,7 +230,7 @@
      * @return the updated value
      */
     public final long decrementAndGet(int i) {
-        return addAndGet(i, -1);
+        return getAndAdd(i, -1) - 1;
     }
 
     /**
@@ -251,13 +241,7 @@
      * @return the updated value
      */
     public long addAndGet(int i, long delta) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            long current = getRaw(offset);
-            long next = current + delta;
-            if (compareAndSetRaw(offset, current, next))
-                return next;
-        }
+        return getAndAdd(i, delta) + delta;
     }
 
     /**
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java	Wed Jan 16 11:58:15 2013 -0800
@@ -98,7 +98,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor.
      */
@@ -118,7 +118,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      * @throws ClassCastException if {@code obj} is not an instance
      * of the class possessing the field established in the constructor.
      */
@@ -162,11 +162,11 @@
      * @return the previous value
      */
     public long getAndSet(T obj, long newValue) {
-        for (;;) {
-            long current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
-        }
+        long prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
     }
 
     /**
@@ -177,12 +177,12 @@
      * @return the previous value
      */
     public long getAndIncrement(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -193,12 +193,12 @@
      * @return the previous value
      */
     public long getAndDecrement(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -210,12 +210,12 @@
      * @return the previous value
      */
     public long getAndAdd(T obj, long delta) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return current;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return prev;
     }
 
     /**
@@ -226,12 +226,12 @@
      * @return the updated value
      */
     public long incrementAndGet(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -242,12 +242,12 @@
      * @return the updated value
      */
     public long decrementAndGet(T obj) {
-        for (;;) {
-            long current = get(obj);
-            long next = current - 1;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev - 1;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     /**
@@ -259,12 +259,12 @@
      * @return the updated value
      */
     public long addAndGet(T obj, long delta) {
-        for (;;) {
-            long current = get(obj);
-            long next = current + delta;
-            if (compareAndSet(obj, current, next))
-                return next;
-        }
+        long prev, next;
+        do {
+            prev = get(obj);
+            next = prev + delta;
+        } while (!compareAndSet(obj, prev, next));
+        return next;
     }
 
     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
@@ -345,6 +345,36 @@
             return unsafe.getLongVolatile(obj, offset);
         }
 
+        public long getAndSet(T obj, long newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            return unsafe.getAndSetLong(obj, offset, newValue);
+        }
+
+        public long getAndIncrement(T obj) {
+            return getAndAdd(obj, 1);
+        }
+
+        public long getAndDecrement(T obj) {
+            return getAndAdd(obj, -1);
+        }
+
+        public long getAndAdd(T obj, long delta) {
+            if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
+            return unsafe.getAndAddLong(obj, offset, delta);
+        }
+
+        public long incrementAndGet(T obj) {
+            return getAndAdd(obj, 1) + 1;
+        }
+
+        public long decrementAndGet(T obj) {
+             return getAndAdd(obj, -1) - 1;
+        }
+
+        public long addAndGet(T obj, long delta) {
+            return getAndAdd(obj, delta) + delta;
+        }
+
         private void ensureProtectedAccess(T obj) {
             if (cclass.isInstance(obj)) {
                 return;
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReference.java	Wed Jan 16 11:58:15 2013 -0800
@@ -124,7 +124,7 @@
      *
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public final boolean weakCompareAndSet(V expect, V update) {
         return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
@@ -136,17 +136,14 @@
      * @param newValue the new value
      * @return the previous value
      */
+    @SuppressWarnings("unchecked")
     public final V getAndSet(V newValue) {
-        while (true) {
-            V x = get();
-            if (compareAndSet(x, newValue))
-                return x;
-        }
+        return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
     }
 
     /**
      * Returns the String representation of the current value.
-     * @return the String representation of the current value.
+     * @return the String representation of the current value
      */
     public String toString() {
         return String.valueOf(get());
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java	Wed Jan 16 11:58:15 2013 -0800
@@ -159,13 +159,9 @@
      * @param newValue the new value
      * @return the previous value
      */
+    @SuppressWarnings("unchecked")
     public final E getAndSet(int i, E newValue) {
-        long offset = checkedByteOffset(i);
-        while (true) {
-            E current = getRaw(offset);
-            if (compareAndSetRaw(offset, current, newValue))
-                return current;
-        }
+        return (E)unsafe.getAndSetObject(array, checkedByteOffset(i), newValue);
     }
 
     /**
@@ -197,7 +193,7 @@
      * @param i the index
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public final boolean weakCompareAndSet(int i, E expect, E update) {
         return compareAndSet(i, expect, update);
--- a/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java	Wed Jan 16 11:58:15 2013 -0800
@@ -116,7 +116,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public abstract boolean compareAndSet(T obj, V expect, V update);
 
@@ -134,7 +134,7 @@
      * @param obj An object whose field to conditionally set
      * @param expect the expected value
      * @param update the new value
-     * @return true if successful.
+     * @return true if successful
      */
     public abstract boolean weakCompareAndSet(T obj, V expect, V update);
 
@@ -176,11 +176,11 @@
      * @return the previous value
      */
     public V getAndSet(T obj, V newValue) {
-        for (;;) {
-            V current = get(obj);
-            if (compareAndSet(obj, current, newValue))
-                return current;
-        }
+        V prev;
+        do {
+            prev = get(obj);
+        } while (!compareAndSet(obj, prev, newValue));
+        return prev;
     }
 
     private static final class AtomicReferenceFieldUpdaterImpl<T,V>
@@ -321,6 +321,15 @@
             return (V)unsafe.getObjectVolatile(obj, offset);
         }
 
+        @SuppressWarnings("unchecked")
+        public V getAndSet(T obj, V newValue) {
+            if (obj == null || obj.getClass() != tclass || cclass != null ||
+                (newValue != null && vclass != null &&
+                 vclass != newValue.getClass()))
+                updateCheck(obj, newValue);
+            return (V)unsafe.getAndSetObject(obj, offset, newValue);
+        }
+
         private void ensureProtectedAccess(T obj) {
             if (cclass.isInstance(obj)) {
                 return;
--- a/jdk/src/share/classes/javax/crypto/Cipher.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/javax/crypto/Cipher.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,17 +104,30 @@
  * must be supplied to GCM/CCM implementations (via the {@code
  * updateAAD} methods) <b>before</b> the ciphertext is processed (via
  * the {@code update} and {@code doFinal} methods).
- *
+ * <p>
+ * Note that GCM mode has a uniqueness requirement on IVs used in
+ * encryption with a given key. When IVs are repeated for GCM
+ * encryption, such usages are subject to forgery attacks. Thus, after
+ * each encryption operation using GCM mode, callers should re-initialize
+ * the cipher objects with GCM parameters which has a different IV value.
  * <pre>
- *     GCMParameterSpec s = new GCMParameterSpec(...);
+ *     GCMParameterSpec s = ...;
  *     cipher.init(..., s);
  *
- *     // If the GCMParameterSpec is needed again
- *     cipher.getParameters().getParameterSpec(GCMParameterSpec.class));
+ *     // If the GCM parameters were generated by the provider, it can
+ *     // be retrieved by:
+ *     // cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
  *
  *     cipher.updateAAD(...);  // AAD
  *     cipher.update(...);     // Multi-part update
  *     cipher.doFinal(...);    // conclusion of operation
+ *
+ *     // Use a different IV value for every encryption
+ *     byte[] newIv = ...;
+ *     s = new GCMParameterSpec(s.getTLen(), newIv);
+ *     cipher.init(..., s);
+ *     ...
+ *
  * </pre>
  * Every implementation of the Java platform is required to support
  * the following standard <code>Cipher</code> transformations with the keysizes
--- a/jdk/src/share/classes/javax/crypto/spec/GCMParameterSpec.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/javax/crypto/spec/GCMParameterSpec.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
  * (Additional Authenticated Data (AAD), Keys, block ciphers,
  * plain/ciphertext and authentication tags) are handled in the {@code
  * Cipher} class.
-  <p>
+ * <p>
  * Please see <a href="http://www.ietf.org/rfc/rfc5116.txt"> RFC 5116
  * </a> for more information on the Authenticated Encryption with
  * Associated Data (AEAD) algorithm, and <a href=
--- a/jdk/src/share/classes/javax/swing/JTable.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/javax/swing/JTable.java	Wed Jan 16 11:58:15 2013 -0800
@@ -3953,7 +3953,7 @@
                     break;
                 case TableModelEvent.INSERT:
                     modelSelection.insertIndexInterval(change.startModelIndex,
-                                                       change.endModelIndex,
+                                                       change.length,
                                                        true);
                     break;
                 default:
--- a/jdk/src/share/classes/sun/launcher/LauncherHelper.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/launcher/LauncherHelper.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -409,6 +409,15 @@
             if (mainValue == null) {
                 abort(null, "java.launcher.jar.error3", jarname);
             }
+            /*
+             * Hand off to FXHelper if it detects a JavaFX application
+             * This must be done after ensuring a Main-Class entry
+             * exists to enforce compliance with the jar specification
+             */
+            if (mainAttrs.containsKey(
+                    new Attributes.Name(FXHelper.JAVAFX_APPLICATION_MARKER))) {
+                return FXHelper.class.getName();
+            }
             return mainValue.trim();
         } catch (IOException ioe) {
             abort(ioe, "java.launcher.jar.error1", jarname);
@@ -483,26 +492,23 @@
         } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
             abort(cnfe, "java.launcher.cls.error1", cn);
         }
-        // set to mainClass, FXHelper may return something else
+        // set to mainClass
         appClass = mainClass;
 
-        Method m = getMainMethod(mainClass);
-        if (m != null) {
-            // this will abort if main method has the wrong signature
-            validateMainMethod(m);
-            return mainClass;
+        /*
+         * Check if FXHelper can launch it using the FX launcher. In an FX app,
+         * the main class may or may not have a main method, so do this before
+         * validating the main class.
+         */
+        if (mainClass.equals(FXHelper.class) ||
+                FXHelper.doesExtendFXApplication(mainClass)) {
+            // Will abort() if there are problems with the FX runtime
+            FXHelper.setFXLaunchParameters(what, mode);
+            return FXHelper.class;
         }
 
-        // Check if FXHelper can launch it using the FX launcher
-        Class<?> fxClass = FXHelper.getFXMainClass(mainClass);
-        if (fxClass != null) {
-            return fxClass;
-        }
-
-        // not an FX application either, abort with an error
-        abort(null, "java.launcher.cls.error4", mainClass.getName(),
-              FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
-        return null; // avoid compiler error...
+        validateMainClass(mainClass);
+        return mainClass;
     }
 
     /*
@@ -515,16 +521,18 @@
         return appClass;
     }
 
-    // Check for main method or return null if not found
-    static Method getMainMethod(Class<?> clazz) {
+    // Check the existence and signature of main and abort if incorrect
+    static void validateMainClass(Class<?> mainClass) {
+        Method mainMethod;
         try {
-            return clazz.getMethod("main", String[].class);
-        } catch (NoSuchMethodException nsme) {}
-        return null;
-    }
+            mainMethod = mainClass.getMethod("main", String[].class);
+        } catch (NoSuchMethodException nsme) {
+            // invalid main or not FX application, abort with an error
+            abort(null, "java.launcher.cls.error4", mainClass.getName(),
+                  FXHelper.JAVAFX_APPLICATION_CLASS_NAME);
+            return; // Avoid compiler issues
+        }
 
-    // Check the signature of main and abort if it's incorrect
-    static void validateMainMethod(Method mainMethod) {
         /*
          * getMethod (above) will choose the correct method, based
          * on its name and parameter type, however, we still have to
@@ -644,41 +652,78 @@
     }
 
     static final class FXHelper {
+        // Marker entry in jar manifest that designates a JavaFX application jar
+        private static final String JAVAFX_APPLICATION_MARKER =
+                "JavaFX-Application-Class";
         private static final String JAVAFX_APPLICATION_CLASS_NAME =
                 "javafx.application.Application";
         private static final String JAVAFX_LAUNCHER_CLASS_NAME =
                 "com.sun.javafx.application.LauncherImpl";
 
         /*
+         * The launch method used to invoke the JavaFX launcher. These must
+         * match the strings used in the launchApplication method.
+         *
+         * Command line                 JavaFX-App-Class  Launch mode  FX Launch mode
+         * java -cp fxapp.jar FXClass   N/A               LM_CLASS     "LM_CLASS"
+         * java -cp somedir FXClass     N/A               LM_CLASS     "LM_CLASS"
+         * java -jar fxapp.jar          Present           LM_JAR       "LM_JAR"
+         * java -jar fxapp.jar          Not Present       LM_JAR       "LM_JAR"
+         */
+        private static final String JAVAFX_LAUNCH_MODE_CLASS = "LM_CLASS";
+        private static final String JAVAFX_LAUNCH_MODE_JAR = "LM_JAR";
+
+        /*
          * FX application launcher and launch method, so we can launch
          * applications with no main method.
          */
+        private static String fxLaunchName = null;
+        private static String fxLaunchMode = null;
+
         private static Class<?> fxLauncherClass    = null;
         private static Method   fxLauncherMethod   = null;
 
         /*
-         * We can assume that the class does NOT have a main method or it would
-         * have been handled already. We do, however, need to check if the class
-         * extends Application and the launcher is available and abort with an
-         * error if it's not.
+         * Set the launch params according to what was passed to LauncherHelper
+         * so we can use the same launch mode for FX. Abort if there is any
+         * issue with loading the FX runtime or with the launcher method.
          */
-        private static Class<?> getFXMainClass(Class<?> mainClass) {
-            // Check if mainClass extends Application
-            if (!doesExtendFXApplication(mainClass)) {
-                return null;
-            }
-
+        private static void setFXLaunchParameters(String what, int mode) {
             // Check for the FX launcher classes
             try {
                 fxLauncherClass = scloader.loadClass(JAVAFX_LAUNCHER_CLASS_NAME);
+                /*
+                 * signature must be:
+                 * public static void launchApplication(String launchName,
+                 *     String launchMode, String[] args);
+                 */
                 fxLauncherMethod = fxLauncherClass.getMethod("launchApplication",
-                        Class.class, String[].class);
+                        String.class, String.class, String[].class);
+
+                // verify launcher signature as we do when validating the main method
+                int mod = fxLauncherMethod.getModifiers();
+                if (!Modifier.isStatic(mod)) {
+                    abort(null, "java.launcher.javafx.error1");
+                }
+                if (fxLauncherMethod.getReturnType() != java.lang.Void.TYPE) {
+                    abort(null, "java.launcher.javafx.error1");
+                }
             } catch (ClassNotFoundException | NoSuchMethodException ex) {
                 abort(ex, "java.launcher.cls.error5", ex);
             }
 
-            // That's all, return this class so we can launch later
-            return FXHelper.class;
+            fxLaunchName = what;
+            switch (mode) {
+                case LM_CLASS:
+                    fxLaunchMode = JAVAFX_LAUNCH_MODE_CLASS;
+                    break;
+                case LM_JAR:
+                    fxLaunchMode = JAVAFX_LAUNCH_MODE_JAR;
+                    break;
+                default:
+                    // should not have gotten this far...
+                    throw new InternalError(mode + ": Unknown launch mode");
+            }
         }
 
         /*
@@ -696,11 +741,15 @@
             return false;
         }
 
-        // preloader ?
         public static void main(String... args) throws Exception {
+            if (fxLauncherMethod == null
+                    || fxLaunchMode == null
+                    || fxLaunchName == null) {
+                throw new RuntimeException("Invalid JavaFX launch parameters");
+            }
             // launch appClass via fxLauncherMethod
-            fxLauncherMethod.invoke(null, new Object[] {appClass, args});
+            fxLauncherMethod.invoke(null,
+                    new Object[] {fxLaunchName, fxLaunchMode, args});
         }
     }
 }
-
--- a/jdk/src/share/classes/sun/launcher/resources/launcher.properties	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/launcher/resources/launcher.properties	Wed Jan 16 11:58:15 2013 -0800
@@ -140,3 +140,6 @@
 java.launcher.jar.error2=manifest not found in {0}
 java.launcher.jar.error3=no main manifest attribute, in {0}
 java.launcher.init.error=initialization error
+java.launcher.javafx.error1=\
+    Error: The JavaFX launchApplication method has the wrong signature, it\n\
+    must be declared static and return a value of type void
--- a/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java	Wed Jan 16 11:58:15 2013 -0800
@@ -206,7 +206,8 @@
 
             if(v == null) {
                 if ((v=schemes.get ("digest")) == null) {
-                    if (((v=schemes.get("ntlm"))==null)) {
+                    if (!NTLMAuthenticationProxy.supported
+                        || ((v=schemes.get("ntlm"))==null)) {
                         v = schemes.get ("basic");
                     }
                 }
--- a/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitSecContextToken.java	Wed Jan 16 11:58:15 2013 -0800
@@ -86,7 +86,7 @@
      * For the context acceptor to call. It reads the bytes out of an
      * InputStream and constructs an InitSecContextToken with them.
      */
-    InitSecContextToken(Krb5Context context, EncryptionKey[] keys,
+    InitSecContextToken(Krb5Context context, Krb5AcceptCredential cred,
                                InputStream is)
         throws IOException, GSSException, KrbException  {
 
@@ -105,7 +105,7 @@
         if (context.getChannelBinding() != null) {
             addr = context.getChannelBinding().getInitiatorAddress();
         }
-        apReq = new KrbApReq(apReqBytes, keys, addr);
+        apReq = new KrbApReq(apReqBytes, cred, addr);
         //debug("\nReceived AP-REQ and authenticated it.\n");
 
         EncryptionKey sessionKey = apReq.getCreds().getSessionKey();
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java	Wed Jan 16 11:58:15 2013 -0800
@@ -45,13 +45,10 @@
 public class Krb5AcceptCredential
     implements Krb5CredElement {
 
-    private static final long serialVersionUID = 7714332137352567952L;
-
-    private Krb5NameElement name;
+    private final Krb5NameElement name;
+    private final ServiceCreds screds;
 
-    private Krb5Util.ServiceCreds screds;
-
-    private Krb5AcceptCredential(Krb5NameElement name, Krb5Util.ServiceCreds creds) {
+    private Krb5AcceptCredential(Krb5NameElement name, ServiceCreds creds) {
         /*
          * Initialize this instance with the data from the acquired
          * KerberosKey. This class needs to be a KerberosKey too
@@ -69,11 +66,11 @@
             name.getKrb5PrincipalName().getName());
         final AccessControlContext acc = AccessController.getContext();
 
-        Krb5Util.ServiceCreds creds = null;
+        ServiceCreds creds = null;
         try {
             creds = AccessController.doPrivileged(
-                        new PrivilegedExceptionAction<Krb5Util.ServiceCreds>() {
-                public Krb5Util.ServiceCreds run() throws Exception {
+                        new PrivilegedExceptionAction<ServiceCreds>() {
+                public ServiceCreds run() throws Exception {
                     return Krb5Util.getServiceCreds(
                         caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller,
                         serverPrinc, acc);
@@ -92,8 +89,10 @@
 
         if (name == null) {
             String fullName = creds.getName();
-            name = Krb5NameElement.getInstance(fullName,
+            if (fullName != null) {
+                name = Krb5NameElement.getInstance(fullName,
                                        Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
+            }
         }
 
         return new Krb5AcceptCredential(name, creds);
@@ -153,8 +152,8 @@
         return Krb5MechFactory.PROVIDER;
     }
 
-    EncryptionKey[] getKrb5EncryptionKeys() {
-        return screds.getEKeys();
+    public EncryptionKey[] getKrb5EncryptionKeys(PrincipalName princ) {
+        return screds.getEKeys(princ);
     }
 
     /**
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Context.java	Wed Jan 16 11:58:15 2013 -0800
@@ -818,16 +818,23 @@
                 }
                 myName = (Krb5NameElement) myCred.getName();
 
-                checkPermission(myName.getKrb5PrincipalName().getName(),
-                                "accept");
-
-                EncryptionKey[] secretKeys =
-                 ((Krb5AcceptCredential) myCred).getKrb5EncryptionKeys();
+                // If there is already a bound name, check now
+                if (myName != null) {
+                    Krb5MechFactory.checkAcceptCredPermission(myName, myName);
+                }
 
                 InitSecContextToken token = new InitSecContextToken(this,
-                                                    secretKeys, is);
+                                                    (Krb5AcceptCredential) myCred, is);
                 PrincipalName clientName = token.getKrbApReq().getClient();
                 peerName = Krb5NameElement.getInstance(clientName);
+
+                // If unbound, check after the bound name is found
+                if (myName == null) {
+                    myName = Krb5NameElement.getInstance(
+                        token.getKrbApReq().getCreds().getServer());
+                    Krb5MechFactory.checkAcceptCredPermission(myName, myName);
+                }
+
                 if (getMutualAuthState()) {
                         retVal = new AcceptSecContextToken(this,
                                           token.getKrbApReq()).encode();
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java	Wed Jan 16 11:58:15 2013 -0800
@@ -158,7 +158,7 @@
     public static void checkAcceptCredPermission(Krb5NameElement name,
                                            GSSNameSpi originalName) {
         SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
+        if (sm != null && name != null) {
             ServicePermission perm = new ServicePermission
                 (name.getKrb5PrincipalName().getName(), "accept");
             try {
--- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5Util.java	Wed Jan 16 11:58:15 2013 -0800
@@ -187,114 +187,6 @@
     }
 
     /**
-     * Credentials of a service, the private secret to authenticate its
-     * identity, which can be:
-     *   1. Some KerberosKeys (generated from password)
-     *   2. A KeyTab (for a typical service)
-     *   3. A TGT (for S4U2proxy extension)
-     *
-     * Note that some creds can coexist. For example, a user2user service
-     * can use its keytab (or keys) if the client can successfully obtain a
-     * normal service ticket, otherwise, it can uses the TGT (actually, the
-     * session key of the TGT) if the client can only acquire a service ticket
-     * of ENC-TKT-IN-SKEY style.
-     */
-    public static class ServiceCreds {
-        private KerberosPrincipal kp;
-        private List<KeyTab> ktabs;
-        private List<KerberosKey> kk;
-        private Subject subj;
-        private KerberosTicket tgt;
-
-        private static ServiceCreds getInstance(
-                Subject subj, String serverPrincipal) {
-
-            ServiceCreds sc = new ServiceCreds();
-            sc.subj = subj;
-
-            for (KerberosPrincipal p: subj.getPrincipals(KerberosPrincipal.class)) {
-                if (serverPrincipal == null ||
-                        p.getName().equals(serverPrincipal)) {
-                    sc.kp = p;
-                    serverPrincipal = p.getName();
-                    break;
-                }
-            }
-            if (sc.kp == null) {
-                // Compatibility with old behavior: even when there is no
-                // KerberosPrincipal, we can find one from KerberosKeys
-                List<KerberosKey> keys = SubjectComber.findMany(
-                        subj, serverPrincipal, null, KerberosKey.class);
-                if (!keys.isEmpty()) {
-                    sc.kp = keys.get(0).getPrincipal();
-                    serverPrincipal = sc.kp.getName();
-                    if (DEBUG) {
-                        System.out.println(">>> ServiceCreds: no kp?"
-                                + " find one from kk: " + serverPrincipal);
-                    }
-                } else {
-                    return null;
-                }
-            }
-            sc.ktabs = SubjectComber.findMany(
-                        subj, null, null, KeyTab.class);
-            sc.kk = SubjectComber.findMany(
-                        subj, serverPrincipal, null, KerberosKey.class);
-            sc.tgt = SubjectComber.find(
-                    subj, null, serverPrincipal, KerberosTicket.class);
-            if (sc.ktabs.isEmpty() && sc.kk.isEmpty() && sc.tgt == null) {
-                return null;
-            }
-            return sc;
-        }
-
-        public String getName() {
-            return kp.getName();
-        }
-
-        public KerberosKey[] getKKeys() {
-            List<KerberosKey> keys = new ArrayList<>();
-            for (KerberosKey k: kk) {
-                keys.add(k);
-            }
-            for (KeyTab ktab: ktabs) {
-                for (KerberosKey k: ktab.getKeys(kp)) {
-                    keys.add(k);
-                }
-            }
-            return keys.toArray(new KerberosKey[keys.size()]);
-        }
-
-        public EncryptionKey[] getEKeys() {
-            KerberosKey[] kkeys = getKKeys();
-            EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
-            for (int i=0; i<ekeys.length; i++) {
-                ekeys[i] =  new EncryptionKey(
-                            kkeys[i].getEncoded(), kkeys[i].getKeyType(),
-                            new Integer(kkeys[i].getVersionNumber()));
-            }
-            return ekeys;
-        }
-
-        public Credentials getInitCred() {
-            if (tgt == null) {
-                return null;
-            }
-            try {
-                return ticketToCreds(tgt);
-            } catch (KrbException | IOException e) {
-                return null;
-            }
-        }
-
-        public void destroy() {
-            kp = null;
-            ktabs = null;
-            kk = null;
-            tgt = null;
-        }
-    }
-    /**
      * Retrieves the ServiceCreds for the specified server principal from
      * the Subject in the specified AccessControlContext. If not found, and if
      * useSubjectCredsOnly is false, then obtain from a LoginContext.
@@ -361,5 +253,4 @@
         return KerberosSecrets.getJavaxSecurityAuthKerberosAccess().
                 keyTabGetEncryptionKeys(ktab, cname);
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/ServiceCreds.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.jgss.krb5;
+
+import javax.security.auth.kerberos.KerberosTicket;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KeyTab;
+import javax.security.auth.Subject;
+
+import sun.security.krb5.Credentials;
+import sun.security.krb5.EncryptionKey;
+import sun.security.krb5.KrbException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import sun.security.krb5.*;
+import sun.security.krb5.internal.Krb5;
+
+/**
+ * Credentials of a kerberos acceptor. A KerberosPrincipal object (kp) is
+ * the principal. It can be specified as the serverPrincipal argument
+ * in the getInstance() method, or uses only KerberosPrincipal in the subject.
+ * Otherwise, the creds object is unbound and kp is null.
+ *
+ * The class also encapsulates various secrets, which can be:
+ *
+ *   1. Some KerberosKeys (generated from password)
+ *   2. Some KeyTabs (for a typical service based on keytabs)
+ *   3. A TGT (for S4U2proxy extension or user2user)
+ *
+ * Note that some secrets can coexist. For example, a user2user service
+ * can use its keytab (or keys) if the client can successfully obtain a
+ * normal service ticket, or it can use the TGT (actually, the session key
+ * of the TGT) if the client can only acquire a service ticket
+ * of ENC-TKT-IN-SKEY style.
+ *
+ * @since 1.8
+ */
+public final class ServiceCreds {
+    // The principal, or null if unbound
+    private KerberosPrincipal kp;
+
+    // All principals in the subject's princ set
+    private Set<KerberosPrincipal> allPrincs;
+
+    // All private credentials that can be used
+    private List<KeyTab> ktabs;
+    private List<KerberosKey> kk;
+    private KerberosTicket tgt;
+
+    private boolean destroyed;
+
+    private ServiceCreds() {
+        // Make sure this class cannot be instantiated externally.
+    }
+
+    /**
+     * Creates a ServiceCreds object based on info in a Subject for
+     * a given principal name (if specified).
+     * @return the object, or null if there is no private creds for it
+     */
+    public static ServiceCreds getInstance(
+            Subject subj, String serverPrincipal) {
+
+        ServiceCreds sc = new ServiceCreds();
+
+        sc.allPrincs =
+                subj.getPrincipals(KerberosPrincipal.class);
+
+        // Compatibility. A key implies its own principal
+        for (KerberosKey key: SubjectComber.findMany(
+                subj, serverPrincipal, null, KerberosKey.class)) {
+            sc.allPrincs.add(key.getPrincipal());
+        }
+
+        if (serverPrincipal != null) {      // A named principal
+            sc.kp = new KerberosPrincipal(serverPrincipal);
+        } else {
+            if (sc.allPrincs.size() == 1) { // choose the only one
+                sc.kp = sc.allPrincs.iterator().next();
+                serverPrincipal = sc.kp.getName();
+            }
+        }
+
+        sc.ktabs = SubjectComber.findMany(
+                    subj, serverPrincipal, null, KeyTab.class);
+        sc.kk = SubjectComber.findMany(
+                    subj, serverPrincipal, null, KerberosKey.class);
+        sc.tgt = SubjectComber.find(
+                subj, null, serverPrincipal, KerberosTicket.class);
+        if (sc.ktabs.isEmpty() && sc.kk.isEmpty() && sc.tgt == null) {
+            return null;
+        }
+
+        sc.destroyed = false;
+
+        return sc;
+    }
+
+    // can be null
+    public String getName() {
+        if (destroyed) {
+            throw new IllegalStateException("This object is destroyed");
+        }
+        return kp == null ? null : kp.getName();
+    }
+
+    /**
+     * Gets keys for someone unknown.
+     * Used by TLS or as a fallback in getEKeys(). Can still return an
+     * empty array.
+     */
+    public KerberosKey[] getKKeys() {
+        if (destroyed) {
+            throw new IllegalStateException("This object is destroyed");
+        }
+        if (kp != null) {
+            return getKKeys(kp);
+        } else if (!allPrincs.isEmpty()) {
+            return getKKeys(allPrincs.iterator().next());
+        }
+        return new KerberosKey[0];
+    }
+
+    /**
+     * Get kkeys for a principal,
+     * @param princ the target name initiator requests. Not null.
+     * @return keys for the princ, never null, might be empty
+     */
+    private KerberosKey[] getKKeys(KerberosPrincipal princ) {
+        ArrayList<KerberosKey> keys = new ArrayList<>();
+        if (kp != null && !princ.equals(kp)) {
+            return new KerberosKey[0];      // Not me
+        }
+        if (!allPrincs.contains(princ)) {
+            return new KerberosKey[0];      // Not someone I know, This check
+                                            // is necessary but a KeyTab has
+                                            // no principal name recorded.
+        }
+        for (KerberosKey k: kk) {
+            if (k.getPrincipal().equals(princ)) {
+                keys.add(k);
+            }
+        }
+        for (KeyTab ktab: ktabs) {
+            for (KerberosKey k: ktab.getKeys(princ)) {
+                keys.add(k);
+            }
+        }
+        return keys.toArray(new KerberosKey[keys.size()]);
+    }
+
+    /**
+     * Gets EKeys for a principal.
+     * @param princ the target name initiator requests. Not null.
+     * @return keys for the princ, never null, might be empty
+     */
+    public EncryptionKey[] getEKeys(PrincipalName princ) {
+        if (destroyed) {
+            throw new IllegalStateException("This object is destroyed");
+        }
+        KerberosKey[] kkeys = getKKeys(new KerberosPrincipal(princ.getName()));
+        if (kkeys.length == 0) {
+            // Note: old JDK does not perform real name checking. If the
+            // acceptor starts by name A but initiator requests for B,
+            // as long as their keys match (i.e. A's keys can decrypt B's
+            // service ticket), the authentication is OK. There are real
+            // customers depending on this to use different names for a
+            // single service.
+            kkeys = getKKeys();
+        }
+        EncryptionKey[] ekeys = new EncryptionKey[kkeys.length];
+        for (int i=0; i<ekeys.length; i++) {
+            ekeys[i] =  new EncryptionKey(
+                        kkeys[i].getEncoded(), kkeys[i].getKeyType(),
+                        new Integer(kkeys[i].getVersionNumber()));
+        }
+        return ekeys;
+    }
+
+    public Credentials getInitCred() {
+        if (destroyed) {
+            throw new IllegalStateException("This object is destroyed");
+        }
+        if (tgt == null) {
+            return null;
+        }
+        try {
+            return Krb5Util.ticketToCreds(tgt);
+        } catch (KrbException | IOException e) {
+            return null;
+        }
+    }
+
+    public void destroy() {
+        // Do not wipe out real keys because they are references to the
+        // priv creds in subject. Just make it useless.
+        destroyed = true;
+        kp = null;
+        ktabs.clear();
+        kk.clear();
+        tgt = null;
+    }
+}
--- a/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/SubjectComber.java	Wed Jan 16 11:58:15 2013 -0800
@@ -33,6 +33,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.kerberos.KeyTab;
 
 /**
@@ -84,19 +85,37 @@
         } else {
             List<T> answer = (oneOnly ? null : new ArrayList<T>());
 
-            if (credClass == KeyTab.class) {    // Principal un-related
-                // We are looking for credentials unrelated to serverPrincipal
-                Iterator<T> iterator =
-                    subject.getPrivateCredentials(credClass).iterator();
-                while (iterator.hasNext()) {
-                    T t = iterator.next();
-                    if (DEBUG) {
-                        System.out.println("Found " + credClass.getSimpleName());
+            if (credClass == KeyTab.class) {
+                // TODO: There is currently no good way to filter out keytabs
+                // not for serverPrincipal. We can only check the principal
+                // set. If the server is not there, we can be sure none of the
+                // keytabs should be used, otherwise, use all for safety.
+                boolean useAll = false;
+                if (serverPrincipal != null) {
+                    for (KerberosPrincipal princ:
+                            subject.getPrincipals(KerberosPrincipal.class)) {
+                        if (princ.getName().equals(serverPrincipal)) {
+                            useAll = true;
+                            break;
+                        }
                     }
-                    if (oneOnly) {
-                        return t;
-                    } else {
-                        answer.add(t);
+                } else {
+                    useAll = true;
+                }
+                if (useAll) {
+                    Iterator<KeyTab> iterator =
+                        subject.getPrivateCredentials(KeyTab.class).iterator();
+                    while (iterator.hasNext()) {
+                        KeyTab t = iterator.next();
+                        if (DEBUG) {
+                            System.out.println("Found " + credClass.getSimpleName()
+                                    + " " + t);
+                        }
+                        if (oneOnly) {
+                            return t;
+                        } else {
+                            answer.add(credClass.cast(t));
+                        }
                     }
                 }
             } else if (credClass == KerberosKey.class) {
@@ -114,11 +133,6 @@
                          if (oneOnly) {
                              return t;
                          } else {
-                             if (serverPrincipal == null) {
-                                 // Record name so that keys returned will all
-                                 // belong to the same principal
-                                 serverPrincipal = name;
-                             }
                              answer.add(credClass.cast(t));
                          }
                     }
--- a/jdk/src/share/classes/sun/security/krb5/KrbApReq.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/KrbApReq.java	Wed Jan 16 11:58:15 2013 -0800
@@ -34,6 +34,7 @@
 import sun.security.krb5.internal.*;
 import sun.security.krb5.internal.crypto.*;
 import sun.security.krb5.internal.rcache.*;
+import sun.security.jgss.krb5.Krb5AcceptCredential;
 import java.net.InetAddress;
 import sun.security.util.*;
 import java.io.IOException;
@@ -135,13 +136,13 @@
      */
      // Used in InitSecContextToken (for AP_REQ and not TGS REQ)
     public KrbApReq(byte[] message,
-                    EncryptionKey[] keys,
+                    Krb5AcceptCredential cred,
                     InetAddress initiator)
         throws KrbException, IOException {
         obuf = message;
         if (apReqMessg == null)
             decode();
-        authenticate(keys, initiator);
+        authenticate(cred, initiator);
     }
 
     /**
@@ -260,10 +261,11 @@
         }
     }
 
-    private void authenticate(EncryptionKey[] keys, InetAddress initiator)
+    private void authenticate(Krb5AcceptCredential cred, InetAddress initiator)
         throws KrbException, IOException {
         int encPartKeyType = apReqMessg.ticket.encPart.getEType();
         Integer kvno = apReqMessg.ticket.encPart.getKeyVersionNumber();
+        EncryptionKey[] keys = cred.getKrb5EncryptionKeys(apReqMessg.ticket.sname);
         EncryptionKey dkey = EncryptionKey.findKey(encPartKeyType, kvno, keys);
 
         if (dkey == null) {
--- a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java	Wed Jan 16 11:58:15 2013 -0800
@@ -382,9 +382,15 @@
      */
     public void addEntry(PrincipalName service, char[] psswd,
             int kvno, boolean append) throws KrbException {
+        addEntry(service, service.getSalt(), psswd, kvno, append);
+    }
+
+    // Called by KDC test
+    public void addEntry(PrincipalName service, String salt, char[] psswd,
+            int kvno, boolean append) throws KrbException {
 
         EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
-            psswd, service.getSalt());
+            psswd, salt);
 
         // There should be only one maximum KVNO value for all etypes, so that
         // all added keys can have the same KVNO.
--- a/jdk/src/share/classes/sun/security/provider/PolicyFile.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/provider/PolicyFile.java	Wed Jan 16 11:58:15 2013 -0800
@@ -31,13 +31,7 @@
 import java.net.URL;
 import java.net.URI;
 import java.util.*;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.ArrayList;
-import java.util.ListIterator;
 import java.text.MessageFormat;
-import com.sun.security.auth.PrincipalComparator;
 import java.security.*;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
@@ -46,19 +40,7 @@
 import java.io.FilePermission;
 import java.net.SocketPermission;
 import java.net.NetPermission;
-import java.util.PropertyPermission;
 import java.util.concurrent.atomic.AtomicReference;
-/*
-import javax.security.auth.AuthPermission;
-import javax.security.auth.kerberos.ServicePermission;
-import javax.security.auth.kerberos.DelegationPermission;
-import java.io.SerializablePermission;
-import java.util.logging.LoggingPermission;
-import java.sql.SQLPermission;
-import java.lang.reflect.ReflectPermission;
-import javax.sound.sampled.AudioPermission;
-import javax.net.ssl.SSLPermission;
-*/
 import sun.misc.JavaSecurityProtectionDomainAccess;
 import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
 import sun.misc.SharedSecrets;
@@ -794,12 +776,9 @@
             debug.println("Adding policy entry: ");
             debug.println("  signedBy " + ge.signedBy);
             debug.println("  codeBase " + ge.codeBase);
-            if (ge.principals != null && ge.principals.size() > 0) {
-                ListIterator<PolicyParser.PrincipalEntry> li =
-                                                ge.principals.listIterator();
-                while (li.hasNext()) {
-                    PolicyParser.PrincipalEntry pppe = li.next();
-                debug.println("  " + pppe.toString());
+            if (ge.principals != null) {
+                for (PolicyParser.PrincipalEntry pppe : ge.principals) {
+                    debug.println("  " + pppe.toString());
                 }
             }
         }
@@ -955,11 +934,15 @@
                InvocationTargetException
     {
         //XXX we might want to keep a hash of created factories...
-        Class<?> pc = Class.forName(type);
+        Class<?> pc = Class.forName(type, false, null);
         Permission answer = getKnownInstance(pc, name, actions);
         if (answer != null) {
             return answer;
         }
+        if (!Permission.class.isAssignableFrom(pc)) {
+            // not the right subtype
+            throw new ClassCastException(type + " is not a Permission");
+        }
 
         if (name == null && actions == null) {
             try {
@@ -1001,7 +984,6 @@
      */
     private static final Permission getKnownInstance(Class<?> claz,
         String name, String actions) {
-        // XXX shorten list to most popular ones?
         if (claz.equals(FilePermission.class)) {
             return new FilePermission(name, actions);
         } else if (claz.equals(SocketPermission.class)) {
@@ -1014,30 +996,6 @@
             return new NetPermission(name, actions);
         } else if (claz.equals(AllPermission.class)) {
             return SecurityConstants.ALL_PERMISSION;
-/*
-        } else if (claz.equals(ReflectPermission.class)) {
-            return new ReflectPermission(name, actions);
-        } else if (claz.equals(SecurityPermission.class)) {
-            return new SecurityPermission(name, actions);
-        } else if (claz.equals(PrivateCredentialPermission.class)) {
-            return new PrivateCredentialPermission(name, actions);
-        } else if (claz.equals(AuthPermission.class)) {
-            return new AuthPermission(name, actions);
-        } else if (claz.equals(ServicePermission.class)) {
-            return new ServicePermission(name, actions);
-        } else if (claz.equals(DelegationPermission.class)) {
-            return new DelegationPermission(name, actions);
-        } else if (claz.equals(SerializablePermission.class)) {
-            return new SerializablePermission(name, actions);
-        } else if (claz.equals(AudioPermission.class)) {
-            return new AudioPermission(name, actions);
-        } else if (claz.equals(SSLPermission.class)) {
-            return new SSLPermission(name, actions);
-        } else if (claz.equals(LoggingPermission.class)) {
-            return new LoggingPermission(name, actions);
-        } else if (claz.equals(SQLPermission.class)) {
-            return new SQLPermission(name, actions);
-*/
         } else {
             return null;
         }
@@ -1079,7 +1037,7 @@
 
             if (cert != null) {
                 if (vcerts == null)
-                    vcerts = new ArrayList<Certificate>();
+                    vcerts = new ArrayList<>();
                 vcerts.add(cert);
             }
         }
@@ -1329,7 +1287,7 @@
 
         List<PolicyParser.PrincipalEntry> entryPs = entry.getPrincipals();
         if (debug != null) {
-            ArrayList<PolicyParser.PrincipalEntry> accPs = new ArrayList<>();
+            List<PolicyParser.PrincipalEntry> accPs = new ArrayList<>();
             if (principals != null) {
                 for (int i = 0; i < principals.length; i++) {
                     accPs.add(new PolicyParser.PrincipalEntry
@@ -1368,79 +1326,72 @@
         // has principals.  see if policy entry principals match
         // principals in current ACC
 
-        for (int i = 0; i < entryPs.size(); i++) {
-            PolicyParser.PrincipalEntry pppe = entryPs.get(i);
+        for (PolicyParser.PrincipalEntry pppe : entryPs) {
 
-            // see if principal entry is a PrincipalComparator
+            // Check for wildcards
+            if (pppe.isWildcardClass()) {
+                // a wildcard class matches all principals in current ACC
+                continue;
+            }
 
-            try {
-                Class<?> pClass = Class.forName
-                                (pppe.principalClass,
-                                true,
-                                Thread.currentThread().getContextClassLoader());
+            if (pppe.isWildcardName()) {
+                // a wildcard name matches any principal with the same class
+                for (Principal p : principals) {
+                    if (pppe.principalClass.equals(p.getClass().getName())) {
+                        continue;
+                    }
+                }
+                if (debug != null) {
+                    debug.println("evaluation (principal name wildcard) failed");
+                }
+                // policy entry principal not in current ACC -
+                // immediately return and go to next policy entry
+                return;
+            }
 
-                if (!PrincipalComparator.class.isAssignableFrom(pClass)) {
-
-                    // common case - dealing with regular Principal class.
-                    // see if policy entry principal is in current ACC
+            Set<Principal> pSet = new HashSet<>(Arrays.asList(principals));
+            Subject subject = new Subject(true, pSet,
+                                          Collections.EMPTY_SET,
+                                          Collections.EMPTY_SET);
+            try {
+                ClassLoader cl = Thread.currentThread().getContextClassLoader();
+                Class<?> pClass = Class.forName(pppe.principalClass, false, cl);
+                if (!Principal.class.isAssignableFrom(pClass)) {
+                    // not the right subtype
+                    throw new ClassCastException(pppe.principalClass +
+                                                 " is not a Principal");
+                }
 
-                    if (!checkEntryPs(principals, pppe)) {
-                        if (debug != null) {
-                            debug.println("evaluation (principals) failed");
-                        }
+                Constructor<?> c = pClass.getConstructor(PARAMS1);
+                Principal p = (Principal)c.newInstance(new Object[] {
+                                                       pppe.principalName });
 
-                        // policy entry principal not in current ACC -
-                        // immediately return and go to next policy entry
-                        return;
+                if (debug != null) {
+                    debug.println("found Principal " + p.getClass().getName());
+                }
+
+                // check if the Principal implies the current
+                // thread's principals
+                if (!p.implies(subject)) {
+                    if (debug != null) {
+                        debug.println("evaluation (principal implies) failed");
                     }
 
-                } else {
-
-                    // dealing with a PrincipalComparator
-
-                    Constructor<?> c = pClass.getConstructor(PARAMS1);
-                    PrincipalComparator pc = (PrincipalComparator)c.newInstance
-                                        (new Object[] { pppe.principalName });
-
-                    if (debug != null) {
-                        debug.println("found PrincipalComparator " +
-                                        pc.getClass().getName());
-                    }
-
-                    // check if the PrincipalComparator
-                    // implies the current thread's principals
-
-                    Set<Principal> pSet = new HashSet<>(principals.length);
-                    for (int j = 0; j < principals.length; j++) {
-                        pSet.add(principals[j]);
-                    }
-                    Subject subject = new Subject(true,
-                                                pSet,
-                                                Collections.EMPTY_SET,
-                                                Collections.EMPTY_SET);
-
-                    if (!pc.implies(subject)) {
-                        if (debug != null) {
-                            debug.println
-                                ("evaluation (principal comparator) failed");
-                        }
-
-                        // policy principal does not imply the current Subject -
-                        // immediately return and go to next policy entry
-                        return;
-                    }
+                    // policy principal does not imply the current Subject -
+                    // immediately return and go to next policy entry
+                    return;
                 }
             } catch (Exception e) {
-                // fall back to regular principal comparison.
+                // fall back to default principal comparison.
                 // see if policy entry principal is in current ACC
 
                 if (debug != null) {
                     e.printStackTrace();
                 }
 
-                if (!checkEntryPs(principals, pppe)) {
+                if (!pppe.implies(subject)) {
                     if (debug != null) {
-                        debug.println("evaluation (principals) failed");
+                        debug.println("evaluation (default principal implies) failed");
                     }
 
                     // policy entry principal not in current ACC -
@@ -1450,7 +1401,7 @@
             }
 
             // either the principal information matched,
-            // or the PrincipalComparator.implies succeeded.
+            // or the Principal.implies succeeded.
             // continue loop and test the next policy principal
         }
 
@@ -1485,47 +1436,6 @@
     }
 
     /**
-     * This method returns, true, if the principal in the policy entry,
-     * pppe, is part of the current thread's principal array, pList.
-     * This method also returns, true, if the policy entry's principal
-     * is appropriately wildcarded.
-     *
-     * Note that the provided <i>pppe</i> argument may have
-     * wildcards (*) for both the <code>Principal</code> class and name.
-     *
-     * @param pList an array of principals from the current thread's
-     *          AccessControlContext.
-     *
-     * @param pppe a Principal specified in a policy grant entry.
-     *
-     * @return true if the current thread's pList "contains" the
-     *          principal in the policy entry, pppe.  This method
-     *          also returns true if the policy entry's principal
-     *          appropriately wildcarded.
-     */
-    private boolean checkEntryPs(Principal[] pList,
-                                PolicyParser.PrincipalEntry pppe) {
-
-        for (int i = 0; i < pList.length; i++) {
-
-            if (pppe.principalClass.equals
-                        (PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
-                pppe.principalClass.equals
-                        (pList[i].getClass().getName())) {
-
-                if (pppe.principalName.equals
-                        (PolicyParser.PrincipalEntry.WILDCARD_NAME) ||
-                    pppe.principalName.equals
-                        (pList[i].getName())) {
-
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
      * <p>
      *
      * @param sp the SelfPermission that needs to be expanded <p>
@@ -1568,8 +1478,7 @@
             sb.append(sp.getSelfName().substring(startIndex, v));
 
             // expand SELF
-            ListIterator<PolicyParser.PrincipalEntry> pli =
-                                                entryPs.listIterator();
+            Iterator<PolicyParser.PrincipalEntry> pli = entryPs.iterator();
             while (pli.hasNext()) {
                 PolicyParser.PrincipalEntry pppe = pli.next();
                 String[][] principalInfo = getPrincipalInfo(pppe,pdp);
@@ -1596,8 +1505,8 @@
         try {
             // first try to instantiate the permission
             perms.add(getInstance(sp.getSelfType(),
-                                sb.toString(),
-                                sp.getSelfActions()));
+                                  sb.toString(),
+                                  sp.getSelfActions()));
         } catch (ClassNotFoundException cnfe) {
             // ok, the permission is not in the bootclasspath.
             // before we add an UnresolvedPermission, check to see
@@ -1673,10 +1582,7 @@
         // 2) the entry's Principal name is wildcarded only
         // 3) the entry's Principal class and name are wildcarded
 
-        if (!pe.principalClass.equals
-            (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
-            !pe.principalName.equals
-            (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
+        if (!pe.isWildcardClass() && !pe.isWildcardName()) {
 
             // build an info array for the principal
             // from the Policy entry
@@ -1685,24 +1591,19 @@
             info[0][1] = pe.principalName;
             return info;
 
-        } else if (!pe.principalClass.equals
-                   (PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
-                   pe.principalName.equals
-                   (PolicyParser.PrincipalEntry.WILDCARD_NAME)) {
+        } else if (!pe.isWildcardClass() && pe.isWildcardName()) {
 
             // build an info array for every principal
             // in the current domain which has a principal class
             // that is equal to policy entry principal class name
             List<Principal> plist = new ArrayList<>();
             for (int i = 0; i < pdp.length; i++) {
-                if(pe.principalClass.equals(pdp[i].getClass().getName()))
+                if (pe.principalClass.equals(pdp[i].getClass().getName()))
                     plist.add(pdp[i]);
             }
             String[][] info = new String[plist.size()][2];
             int i = 0;
-            java.util.Iterator<Principal> pIterator = plist.iterator();
-            while (pIterator.hasNext()) {
-                Principal p = pIterator.next();
+            for (Principal p : plist) {
                 info[i][0] = p.getClass().getName();
                 info[i][1] = p.getName();
                 i++;
@@ -1763,7 +1664,7 @@
             // Done
             return certs;
 
-        ArrayList<Certificate> userCertList = new ArrayList<>();
+        List<Certificate> userCertList = new ArrayList<>();
         i = 0;
         while (i < certs.length) {
             userCertList.add(certs[i]);
@@ -1889,10 +1790,8 @@
         if (principals == null || principals.isEmpty() || keystore == null)
             return true;
 
-        ListIterator<PolicyParser.PrincipalEntry> i = principals.listIterator();
-        while (i.hasNext()) {
-            PolicyParser.PrincipalEntry pppe = i.next();
-            if (pppe.principalClass.equals(PolicyParser.REPLACE_NAME)) {
+        for (PolicyParser.PrincipalEntry pppe : principals) {
+            if (pppe.isReplaceName()) {
 
                 // perform replacement
                 // (only X509 replacement is possible now)
@@ -2241,8 +2140,7 @@
 
                     if (this.certs == null) {
                         // extract the signer certs
-                        ArrayList<Certificate> signerCerts =
-                            new ArrayList<>();
+                        List<Certificate> signerCerts = new ArrayList<>();
                         i = 0;
                         while (i < certs.length) {
                             signerCerts.add(certs[i]);
@@ -2406,11 +2304,10 @@
         private java.util.Random random;
 
         PolicyInfo(int numCaches) {
-            policyEntries = new ArrayList<PolicyEntry>();
+            policyEntries = new ArrayList<>();
             identityPolicyEntries =
                 Collections.synchronizedList(new ArrayList<PolicyEntry>(2));
-            aliasMapping = Collections.synchronizedMap(
-                    new HashMap<Object, Object>(11));
+            aliasMapping = Collections.synchronizedMap(new HashMap<>(11));
 
             pdMapping = new ProtectionDomainCache[numCaches];
             JavaSecurityProtectionDomainAccess jspda
--- a/jdk/src/share/classes/sun/security/provider/PolicyParser.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/provider/PolicyParser.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,16 +29,17 @@
 import java.lang.RuntimePermission;
 import java.net.SocketPermission;
 import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.Principal;
+import java.text.MessageFormat;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.LinkedList;
-import java.util.ListIterator;
 import java.util.Vector;
 import java.util.StringTokenizer;
-import java.text.MessageFormat;
 import javax.security.auth.x500.X500Principal;
 
-import java.security.GeneralSecurityException;
 import sun.security.util.Debug;
 import sun.security.util.PropertyExpander;
 import sun.security.util.ResourcesMgr;
@@ -72,7 +73,7 @@
  *  Permissions perms = policy.getPermissions(protectiondomain)
  * </pre>
  *
- * <p>The protection domain contains CodeSource
+ * <p>The protection domain contains a CodeSource
  * object, which encapsulates its codebase (URL) and public key attributes.
  * It also contains the principals associated with the domain.
  * The Policy object evaluates the global policy in light of who the
@@ -87,9 +88,6 @@
 
 public class PolicyParser {
 
-    // needs to be public for PolicyTool
-    public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME";
-
     private static final String EXTDIRS_PROPERTY = "java.ext.dirs";
     private static final String OLD_EXTDIRS_EXPANSION =
         "${" + EXTDIRS_PROPERTY + "}";
@@ -452,7 +450,7 @@
                 peekAndMatch(",");
             } else if (peekAndMatch("Principal")) {
                 if (principals == null) {
-                    principals = new LinkedList<PrincipalEntry>();
+                    principals = new LinkedList<>();
                 }
 
                 String principalClass;
@@ -461,7 +459,7 @@
                 if (peek("\"")) {
                     // both the principalClass and principalName
                     // will be replaced later
-                    principalClass = REPLACE_NAME;
+                    principalClass = PrincipalEntry.REPLACE_NAME;
                     principalName = match("principal type");
                 } else {
                     // check for principalClass wildcard
@@ -916,7 +914,7 @@
                     out.print(",\n");
             }
             if (principals != null && principals.size() > 0) {
-                ListIterator<PrincipalEntry> pli = principals.listIterator();
+                Iterator<PrincipalEntry> pli = principals.iterator();
                 while (pli.hasNext()) {
                     out.print("      ");
                     PrincipalEntry pe = pli.next();
@@ -949,23 +947,22 @@
     /**
      * Principal info (class and name) in a grant entry
      */
-    public static class PrincipalEntry {
+    public static class PrincipalEntry implements Principal {
 
         public static final String WILDCARD_CLASS = "WILDCARD_PRINCIPAL_CLASS";
         public static final String WILDCARD_NAME = "WILDCARD_PRINCIPAL_NAME";
+        public static final String REPLACE_NAME = "PolicyParser.REPLACE_NAME";
 
         String principalClass;
         String principalName;
 
         /**
-         * A PrincipalEntry consists of the <code>Principal</code>
-         * class and <code>Principal</code> name.
+         * A PrincipalEntry consists of the Principal class and Principal name.
          *
-         * <p>
-         *
-         * @param principalClass the <code>Principal</code> class. <p>
-         *
-         * @param principalName the <code>Principal</code> name. <p>
+         * @param principalClass the Principal class
+         * @param principalName the Principal name
+         * @throws NullPointerException if principalClass or principalName
+         *                              are null
          */
         public PrincipalEntry(String principalClass, String principalName) {
             if (principalClass == null || principalName == null)
@@ -975,6 +972,18 @@
             this.principalName = principalName;
         }
 
+        boolean isWildcardName() {
+            return principalName.equals(WILDCARD_NAME);
+        }
+
+        boolean isWildcardClass() {
+            return principalClass.equals(WILDCARD_CLASS);
+        }
+
+        boolean isReplaceName() {
+            return principalClass.equals(REPLACE_NAME);
+        }
+
         public String getPrincipalClass() {
             return principalClass;
         }
@@ -984,9 +993,9 @@
         }
 
         public String getDisplayClass() {
-            if (principalClass.equals(WILDCARD_CLASS)) {
+            if (isWildcardClass()) {
                 return "*";
-            } else if (principalClass.equals(REPLACE_NAME)) {
+            } else if (isReplaceName()) {
                 return "";
             }
             else return principalClass;
@@ -997,7 +1006,7 @@
         }
 
         public String getDisplayName(boolean addQuote) {
-            if (principalName.equals(WILDCARD_NAME)) {
+            if (isWildcardName()) {
                 return "*";
             }
             else {
@@ -1006,8 +1015,14 @@
             }
         }
 
+        @Override
+        public String getName() {
+            return principalName;
+        }
+
+        @Override
         public String toString() {
-            if (!principalClass.equals(REPLACE_NAME)) {
+            if (!isReplaceName()) {
                 return getDisplayClass() + "/" + getDisplayName();
             } else {
                 return getDisplayName();
@@ -1016,15 +1031,13 @@
 
         /**
          * Test for equality between the specified object and this object.
-         * Two PrincipalEntries are equal if their PrincipalClass and
-         * PrincipalName values are equal.
-         *
-         * <p>
+         * Two PrincipalEntries are equal if their class and name values
+         * are equal.
          *
-         * @param obj the object to test for equality with this object.
-         *
-         * @return true if the objects are equal, false otherwise.
+         * @param obj the object to test for equality with this object
+         * @return true if the objects are equal, false otherwise
          */
+        @Override
         public boolean equals(Object obj) {
             if (this == obj)
                 return true;
@@ -1033,27 +1046,23 @@
                 return false;
 
             PrincipalEntry that = (PrincipalEntry)obj;
-            if (this.principalClass.equals(that.principalClass) &&
-                this.principalName.equals(that.principalName)) {
-                return true;
-            }
-
-            return false;
+            return (principalClass.equals(that.principalClass) &&
+                    principalName.equals(that.principalName));
         }
 
         /**
-         * Return a hashcode for this <code>PrincipalEntry</code>.
+         * Return a hashcode for this PrincipalEntry.
          *
-         * <p>
-         *
-         * @return a hashcode for this <code>PrincipalEntry</code>.
+         * @return a hashcode for this PrincipalEntry
          */
+        @Override
         public int hashCode() {
             return principalClass.hashCode();
         }
+
         public void write(PrintWriter out) {
             out.print("principal " + getDisplayClass() + " " +
-                getDisplayName(true));
+                      getDisplayName(true));
         }
     }
 
@@ -1101,6 +1110,7 @@
          * Calculates a hash code value for the object.  Objects
          * which are equal will also have the same hashcode.
          */
+        @Override
         public int hashCode() {
             int retval = permission.hashCode();
             if (name != null) retval ^= name.hashCode();
@@ -1108,6 +1118,7 @@
             return retval;
         }
 
+        @Override
         public boolean equals(Object obj) {
             if (obj == this)
                 return true;
@@ -1210,28 +1221,18 @@
             i18nMessage = form.format(source);
         }
 
+        @Override
         public String getLocalizedMessage() {
             return i18nMessage;
         }
     }
 
     public static void main(String arg[]) throws Exception {
-        FileReader fr = null;
-        FileWriter fw = null;
-        try {
+        try (FileReader fr = new FileReader(arg[0]);
+             FileWriter fw = new FileWriter(arg[1])) {
             PolicyParser pp = new PolicyParser(true);
-            fr = new FileReader(arg[0]);
             pp.read(fr);
-            fw = new FileWriter(arg[1]);
             pp.write(fw);
-        } finally {
-            if (fr != null) {
-                fr.close();
-            }
-
-            if (fw != null) {
-                fw.close();
-            }
         }
     }
 }
--- a/jdk/src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/ssl/krb5/Krb5ProxyImpl.java	Wed Jan 16 11:58:15 2013 -0800
@@ -36,6 +36,7 @@
 
 import sun.security.jgss.GSSCaller;
 import sun.security.jgss.krb5.Krb5Util;
+import sun.security.jgss.krb5.ServiceCreds;
 import sun.security.krb5.PrincipalName;
 import sun.security.ssl.Krb5Proxy;
 
@@ -62,7 +63,7 @@
     @Override
     public SecretKey[] getServerKeys(AccessControlContext acc)
             throws LoginException {
-        Krb5Util.ServiceCreds serviceCreds =
+        ServiceCreds serviceCreds =
             Krb5Util.getServiceCreds(GSSCaller.CALLER_SSL_SERVER, null, acc);
         return serviceCreds != null ? serviceCreds.getKKeys() :
                                         new KerberosKey[0];
--- a/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/classes/sun/security/tools/policytool/PolicyTool.java	Wed Jan 16 11:58:15 2013 -0800
@@ -604,7 +604,7 @@
                InstantiationException
     {
         if (type.equals(PolicyParser.PrincipalEntry.WILDCARD_CLASS) ||
-            type.equals(PolicyParser.REPLACE_NAME)) {
+            type.equals(PolicyParser.PrincipalEntry.REPLACE_NAME)) {
             return;
         }
         Class<?> PRIN = Class.forName("java.security.Principal");
@@ -2094,7 +2094,7 @@
         } else if (pclass.equals("")) {
             // make this consistent with what PolicyParser does
             // when it sees an empty principal class
-            pclass = PolicyParser.REPLACE_NAME;
+            pclass = PolicyParser.PrincipalEntry.REPLACE_NAME;
             tool.warnings.addElement(
                         "Warning: Principal name '" + pname +
                                 "' specified without a Principal class.\n" +
--- a/jdk/src/share/native/java/lang/System.c	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/share/native/java/lang/System.c	Wed Jan 16 11:58:15 2013 -0800
@@ -389,11 +389,19 @@
         sprops->display_variant, sprops->format_variant, putID, getPropID);
     GETPROP(props, "file.encoding", jVMVal);
     if (jVMVal == NULL) {
+#ifdef MACOSX
+        /*
+         * Since sun_jnu_encoding is now hard-coded to UTF-8 on Mac, we don't
+         * want to use it to overwrite file.encoding
+         */
+        PUTPROP(props, "file.encoding", sprops->encoding);
+#else
         if (fmtdefault) {
             PUTPROP(props, "file.encoding", sprops->encoding);
         } else {
             PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
         }
+#endif
     } else {
         (*env)->DeleteLocalRef(env, jVMVal);
     }
--- a/jdk/src/solaris/native/java/lang/java_props_md.c	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/solaris/native/java/lang/java_props_md.c	Wed Jan 16 11:58:15 2013 -0800
@@ -538,7 +538,12 @@
     sprops.display_script = sprops.script;
     sprops.display_country = sprops.country;
     sprops.display_variant = sprops.variant;
+
+#ifdef MACOSX
+    sprops.sun_jnu_encoding = "UTF-8";
+#else
     sprops.sun_jnu_encoding = sprops.encoding;
+#endif
 
 #ifdef _ALLBSD_SOURCE
 #if BYTE_ORDER == _LITTLE_ENDIAN
--- a/jdk/src/windows/classes/sun/nio/ch/PipeImpl.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/src/windows/classes/sun/nio/ch/PipeImpl.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,67 +72,97 @@
 
         private final SelectorProvider sp;
 
+        private IOException ioe = null;
+
         private Initializer(SelectorProvider sp) {
             this.sp = sp;
         }
 
+        @Override
         public Void run() throws IOException {
-            ServerSocketChannel ssc = null;
-            SocketChannel sc1 = null;
-            SocketChannel sc2 = null;
-
-            try {
-                // loopback address
-                InetAddress lb = InetAddress.getByName("127.0.0.1");
-                assert(lb.isLoopbackAddress());
-
-                // bind ServerSocketChannel to a port on the loopback address
-                ssc = ServerSocketChannel.open();
-                ssc.socket().bind(new InetSocketAddress(lb, 0));
-
-                // Establish connection (assumes connections are eagerly
-                // accepted)
-                InetSocketAddress sa
-                    = new InetSocketAddress(lb, ssc.socket().getLocalPort());
-                sc1 = SocketChannel.open(sa);
-
-                ByteBuffer bb = ByteBuffer.allocate(8);
-                long secret = rnd.nextLong();
-                bb.putLong(secret).flip();
-                sc1.write(bb);
-
-                // Get a connection and verify it is legitimate
+            LoopbackConnector connector = new LoopbackConnector();
+            connector.run();
+            if (ioe instanceof ClosedByInterruptException) {
+                ioe = null;
+                Thread connThread = new Thread(connector) {
+                    @Override
+                    public void interrupt() {}
+                };
+                connThread.start();
                 for (;;) {
-                    sc2 = ssc.accept();
-                    bb.clear();
-                    sc2.read(bb);
-                    bb.rewind();
-                    if (bb.getLong() == secret)
+                    try {
+                        connThread.join();
                         break;
-                    sc2.close();
+                    } catch (InterruptedException ex) {}
                 }
+                Thread.currentThread().interrupt();
+            }
+
+            if (ioe != null)
+                throw new IOException("Unable to establish loopback connection", ioe);
 
-                // Create source and sink channels
-                source = new SourceChannelImpl(sp, sc1);
-                sink = new SinkChannelImpl(sp, sc2);
-            } catch (IOException e) {
+            return null;
+        }
+
+        private class LoopbackConnector implements Runnable {
+
+            @Override
+            public void run() {
+                ServerSocketChannel ssc = null;
+                SocketChannel sc1 = null;
+                SocketChannel sc2 = null;
+
                 try {
-                    if (sc1 != null)
-                        sc1.close();
-                    if (sc2 != null)
+                    // Loopback address
+                    InetAddress lb = InetAddress.getByName("127.0.0.1");
+                    assert(lb.isLoopbackAddress());
+                    InetSocketAddress sa = null;
+                    for(;;) {
+                        // Bind ServerSocketChannel to a port on the loopback
+                        // address
+                        if (ssc == null || !ssc.isOpen()) {
+                            ssc = ServerSocketChannel.open();
+                            ssc.socket().bind(new InetSocketAddress(lb, 0));
+                            sa = new InetSocketAddress(lb, ssc.socket().getLocalPort());
+                        }
+
+                        // Establish connection (assume connections are eagerly
+                        // accepted)
+                        sc1 = SocketChannel.open(sa);
+                        ByteBuffer bb = ByteBuffer.allocate(8);
+                        long secret = rnd.nextLong();
+                        bb.putLong(secret).flip();
+                        sc1.write(bb);
+
+                        // Get a connection and verify it is legitimate
+                        sc2 = ssc.accept();
+                        bb.clear();
+                        sc2.read(bb);
+                        bb.rewind();
+                        if (bb.getLong() == secret)
+                            break;
                         sc2.close();
-                } catch (IOException e2) { }
-                IOException x = new IOException("Unable to establish"
-                                                + " loopback connection");
-                x.initCause(e);
-                throw x;
-            } finally {
-                try {
-                    if (ssc != null)
-                        ssc.close();
-                } catch (IOException e2) { }
+                        sc1.close();
+                    }
+
+                    // Create source and sink channels
+                    source = new SourceChannelImpl(sp, sc1);
+                    sink = new SinkChannelImpl(sp, sc2);
+                } catch (IOException e) {
+                    try {
+                        if (sc1 != null)
+                            sc1.close();
+                        if (sc2 != null)
+                            sc2.close();
+                    } catch (IOException e2) {}
+                    ioe = e;
+                } finally {
+                    try {
+                        if (ssc != null)
+                            ssc.close();
+                    } catch (IOException e2) {}
+                }
             }
-            return null;
         }
     }
 
@@ -144,7 +174,6 @@
         }
     }
 
-
     public SourceChannel source() {
         return source;
     }
--- a/jdk/test/ProblemList.txt	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/ProblemList.txt	Wed Jan 16 11:58:15 2013 -0800
@@ -1,6 +1,6 @@
 ###########################################################################
 #
-# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -122,9 +122,6 @@
 
 # jdk_lang
 
-# 7194607
-java/lang/instrument/VerifyLocalVariableTableOnRetransformTest.sh generic-all
-
 # 6944188
 java/lang/management/ThreadMXBean/ThreadStateTest.java          generic-all
 
@@ -148,6 +145,9 @@
 # 6959636
 javax/management/loading/LibraryLoader/LibraryLoaderTest.java	windows-all
 
+# 8005472
+com/sun/jmx/remote/NotificationMarshalVersions/TestSerializationMismatch.sh windows-all
+
 ############################################################################
 
 # jdk_math
@@ -238,9 +238,6 @@
 # 7146541
 java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java	linux-all
 
-# 7187882
-java/rmi/activation/checkusage/CheckUsage.java                  generic-all
-
 # 7190106
 java/rmi/reliability/benchmark/runRmiBench.sh                   generic-all
 
@@ -324,6 +321,9 @@
 # 7150569
 tools/launcher/UnicodeTest.java                                 macosx-all
 
+# 8005252
+tools/pack200/AttributeTests.java                               generic-all
+
 ############################################################################
 
 # jdk_jdi
--- a/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4512524.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4512524.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,13 +40,13 @@
 public class Test4512524 {
 
     private static final String ALGO = "AES";
-    private static final String MODE = "CBC";
     private static final String PADDING = "NoPadding";
     private static final int KEYSIZE = 16; // in bytes
 
-    public boolean execute() throws Exception {
+    public void execute(String mode) throws Exception {
 
-        Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
+        String transformation = ALGO+"/"+mode+"/"+PADDING;
+        Cipher ci = Cipher.getInstance(transformation, "SunJCE");
 
         // TEST FIX 4512524
         KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
@@ -61,17 +61,14 @@
         }
 
         // passed all tests...hooray!
-        return true;
+        System.out.println(transformation + ": Passed");
     }
 
     public static void main (String[] args) throws Exception {
         Security.addProvider(new com.sun.crypto.provider.SunJCE());
 
         Test4512524 test = new Test4512524();
-        String testName = test.getClass().getName() + "[" + ALGO +
-            "/" + MODE + "/" + PADDING + "]";
-        if (test.execute()) {
-            System.out.println(testName + ": Passed!");
-        }
+        test.execute("CBC");
+        test.execute("GCM");
     }
 }
--- a/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4512704.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4512704.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,14 +39,14 @@
 
 public class Test4512704 {
     private static final String ALGO = "AES";
-    private static final String MODE = "CBC";
-    private static final String PADDING = "PKCS5Padding";
+    private static final String PADDING = "NoPadding";
     private static final int KEYSIZE = 16; // in bytes
 
-    public boolean execute() throws Exception {
+    public void execute(String mode) throws Exception {
+
         AlgorithmParameterSpec aps = null;
-
-        Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
+        String transformation = ALGO + "/" + mode + "/"+PADDING;
+        Cipher ci = Cipher.getInstance(transformation, "SunJCE");
 
         KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
         kg.init(KEYSIZE*8);
@@ -57,19 +57,14 @@
         } catch(InvalidAlgorithmParameterException ex) {
             throw new Exception("parameter should be generated when null is specified!");
         }
-
-        // passed all tests...hooray!
-        return true;
+        System.out.println(transformation + ": Passed");
     }
 
     public static void main (String[] args) throws Exception {
         Security.addProvider(new com.sun.crypto.provider.SunJCE());
 
         Test4512704 test = new Test4512704();
-        String testName = test.getClass().getName() + "[" + ALGO +
-            "/" + MODE + "/" + PADDING + "]";
-        if (test.execute()) {
-            System.out.println(testName + ": Passed!");
-        }
+        test.execute("CBC");
+        test.execute("GCM");
     }
 }
--- a/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4517355.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4517355.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,16 +41,14 @@
 public class Test4517355 {
 
     private static final String ALGO = "AES";
-    private static final String MODE = "CBC";
-    private static final String PADDING = "PKCS5Padding";
     private static final int KEYSIZE = 16; // in bytes
 
-    public boolean execute() throws Exception {
-        Random rdm = new Random();
-        byte[] plainText=new byte[125];
-        rdm.nextBytes(plainText);
+    private static byte[] plainText = new byte[125];
 
-        Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
+    public void execute(String mode, String padding) throws Exception {
+        String transformation = ALGO + "/" + mode + "/" + padding;
+
+        Cipher ci = Cipher.getInstance(transformation, "SunJCE");
         KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
         kg.init(KEYSIZE*8);
         SecretKey key = kg.generateKey();
@@ -59,9 +57,14 @@
         ci.init(Cipher.ENCRYPT_MODE, key);
         byte[] cipherText = ci.doFinal(plainText);
 
-        byte[] iv = ci.getIV();
-        AlgorithmParameterSpec aps = new IvParameterSpec(iv);
-        ci.init(Cipher.DECRYPT_MODE, key, aps);
+        if (mode.equalsIgnoreCase("GCM")) {
+            AlgorithmParameters params = ci.getParameters();
+            ci.init(Cipher.DECRYPT_MODE, key, params);
+        } else {
+            byte[] iv = ci.getIV();
+            AlgorithmParameterSpec aps = new IvParameterSpec(iv);
+            ci.init(Cipher.DECRYPT_MODE, key, aps);
+        }
         byte[] recoveredText = new byte[plainText.length];
         try {
             int len = ci.doFinal(cipherText, 0, cipherText.length,
@@ -80,21 +83,22 @@
             throw new Exception("encryption does not work!");
         }
         // 3. make sure padding is working
-        if ((cipherText.length/16)*16 != cipherText.length) {
-            throw new Exception("padding does not work!");
+        if (padding.equalsIgnoreCase("PKCS5Padding")) {
+            if ((cipherText.length/16)*16 != cipherText.length) {
+                throw new Exception("padding does not work!");
+            }
         }
-        // passed all tests...hooray!
-        return true;
+        System.out.println(transformation + ": Passed");
     }
 
     public static void main (String[] args) throws Exception {
         Security.addProvider(new com.sun.crypto.provider.SunJCE());
 
         Test4517355 test = new Test4517355();
-        String testName = test.getClass().getName() + "[" + ALGO +
-            "/" + MODE + "/" + PADDING + "]";
-        if (test.execute()) {
-            System.out.println(testName + ": Passed!");
-        }
+        Random rdm = new Random();
+        rdm.nextBytes(test.plainText);
+
+        test.execute("CBC", "PKCS5Padding");
+        test.execute("GCM", "NoPadding");
     }
 }
--- a/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4626070.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/Test4626070.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,13 +34,11 @@
 
 public class Test4626070 {
     private static final String ALGO = "AES";
-    private static final String MODE = "CBC";
-    private static final String PADDING = "PKCS5Padding";
     private static final int KEYSIZE = 16; // in bytes
 
-    public boolean execute() throws Exception {
-
-        Cipher ci = Cipher.getInstance(ALGO+"/"+MODE+"/"+PADDING, "SunJCE");
+    public void execute(String mode, String padding) throws Exception {
+        String transformation = ALGO + "/" + mode + "/" + padding;
+        Cipher ci = Cipher.getInstance(transformation, "SunJCE");
         KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE");
         kg.init(KEYSIZE*8);
         SecretKey key = kg.generateKey();
@@ -58,18 +56,14 @@
             throw new Exception(
                 "key after wrap/unwrap is different from the original!");
         }
-        // passed all tests...hooray!
-        return true;
+        System.out.println(transformation + ": Passed");
     }
 
     public static void main (String[] args) throws Exception {
         Security.addProvider(new com.sun.crypto.provider.SunJCE());
 
         Test4626070 test = new Test4626070();
-        String testName = test.getClass().getName() + "[" + ALGO +
-            "/" + MODE + "/" + PADDING + "]";
-        if (test.execute()) {
-            System.out.println(testName + ": Passed!");
-        }
+        test.execute("CBC", "PKCS5Padding");
+        test.execute("GCM", "NoPadding");
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestGCMKeyAndIvCheck.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6996769
+ * @library ../UTIL
+ * @build TestUtil
+ * @run main TestGCMKeyAndIvCheck
+ * @summary Ensure that same key+iv can't be repeated used for encryption.
+ * @author Valerie Peng
+ */
+
+
+import java.security.*;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+import java.math.*;
+import com.sun.crypto.provider.*;
+
+import java.util.*;
+
+public class TestGCMKeyAndIvCheck {
+
+    private static final byte[] AAD = new byte[5];
+    private static final byte[] PT = new byte[18];
+
+    private static void checkISE(Cipher c) throws Exception {
+        // Subsequent encryptions should fail
+        try {
+            c.updateAAD(AAD);
+            throw new Exception("Should throw ISE for updateAAD()");
+        } catch (IllegalStateException ise) {
+            // expected
+        }
+
+        try {
+            c.update(PT);
+            throw new Exception("Should throw ISE for update()");
+        } catch (IllegalStateException ise) {
+            // expected
+        }
+        try {
+            c.doFinal(PT);
+            throw new Exception("Should throw ISE for doFinal()");
+        } catch (IllegalStateException ise) {
+            // expected
+        }
+    }
+
+    public void test() throws Exception {
+        Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
+
+        SecretKey key = new SecretKeySpec(new byte[16], "AES");
+        // First try parameter-less init.
+        c.init(Cipher.ENCRYPT_MODE, key);
+        c.updateAAD(AAD);
+        byte[] ctPlusTag = c.doFinal(PT);
+
+        // subsequent encryption should fail unless re-init w/ different key+iv
+        checkISE(c);
+
+        // Validate the retrieved parameters against the IV and tag length.
+        AlgorithmParameters params = c.getParameters();
+        if (params == null) {
+            throw new Exception("getParameters() should not return null");
+        }
+        GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
+        if (spec.getTLen() != (ctPlusTag.length - PT.length)*8) {
+            throw new Exception("Parameters contains incorrect TLen value");
+        }
+        if (!Arrays.equals(spec.getIV(), c.getIV())) {
+            throw new Exception("Parameters contains incorrect IV value");
+        }
+
+        // Should be ok to use the same key+iv for decryption
+        c.init(Cipher.DECRYPT_MODE, key, params);
+        c.updateAAD(AAD);
+        byte[] recovered = c.doFinal(ctPlusTag);
+        if (!Arrays.equals(recovered, PT)) {
+            throw new Exception("decryption result mismatch");
+        }
+
+        // Now try to encrypt again using the same key+iv; should fail also
+        try {
+            c.init(Cipher.ENCRYPT_MODE, key, params);
+            throw new Exception("Should throw exception when same key+iv is used");
+        } catch (InvalidAlgorithmParameterException iape) {
+            // expected
+        }
+
+        // Now try to encrypt again using parameter-less init; should work
+        c.init(Cipher.ENCRYPT_MODE, key);
+        c.doFinal(PT);
+
+        // make sure a different iv is used
+        byte[] iv = c.getIV();
+        if (Arrays.equals(spec.getIV(), iv)) {
+            throw new Exception("IV should be different now");
+        }
+
+        // Now try to encrypt again using a different parameter; should work
+        c.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, new byte[30]));
+        c.updateAAD(AAD);
+        c.doFinal(PT);
+        // subsequent encryption should fail unless re-init w/ different key+iv
+        checkISE(c);
+
+        // Now try decryption twice in a row; no re-init required and
+        // same parameters is used.
+        c.init(Cipher.DECRYPT_MODE, key, params);
+        c.updateAAD(AAD);
+        recovered = c.doFinal(ctPlusTag);
+
+        c.updateAAD(AAD);
+        recovered = c.doFinal(ctPlusTag);
+        if (!Arrays.equals(recovered, PT)) {
+            throw new Exception("decryption result mismatch");
+        }
+
+        // Now try decryption again and re-init using the same parameters
+        c.init(Cipher.DECRYPT_MODE, key, params);
+        c.updateAAD(AAD);
+        recovered = c.doFinal(ctPlusTag);
+
+        // init to decrypt w/o parameters; should fail with IKE as
+        // javadoc specified
+        try {
+            c.init(Cipher.DECRYPT_MODE, key);
+            throw new Exception("Should throw IKE for dec w/o params");
+        } catch (InvalidKeyException ike) {
+            // expected
+        }
+
+        // Lastly, try encryption AND decryption w/ wrong type of parameters,
+        // e.g. IvParameterSpec
+        try {
+            c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
+            throw new Exception("Should throw IAPE");
+        } catch (InvalidAlgorithmParameterException iape) {
+            // expected
+        }
+        try {
+            c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
+            throw new Exception("Should throw IAPE");
+        } catch (InvalidAlgorithmParameterException iape) {
+            // expected
+        }
+
+        System.out.println("Test Passed!");
+    }
+
+    public static void main (String[] args) throws Exception {
+        TestGCMKeyAndIvCheck t = new TestGCMKeyAndIvCheck();
+        t.test();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestKATForGCM.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6996769
+ * @library ../UTIL
+ * @build TestUtil
+ * @run main TestKATForGCM
+ * @summary Known Answer Test for AES cipher with GCM mode support in
+ * SunJCE provider.
+ * @author Valerie Peng
+ */
+
+
+import java.security.*;
+import javax.crypto.*;
+import javax.crypto.spec.*;
+import java.math.*;
+import com.sun.crypto.provider.*;
+
+import java.util.*;
+
+public class TestKATForGCM {
+
+    // Utility methods
+    private static byte[] HexToBytes(String hexVal) {
+        if (hexVal == null) return new byte[0];
+        byte[] result = new byte[hexVal.length()/2];
+        for (int i = 0; i < result.length; i++) {
+            // 2 characters at a time
+            String byteVal = hexVal.substring(2*i, 2*i +2);
+            result[i] = Integer.valueOf(byteVal, 16).byteValue();
+        }
+        return result;
+    }
+
+    private static class TestVector {
+        SecretKey key;
+        byte[] plainText;
+        byte[] aad;
+        byte[] cipherText;
+        byte[] tag;
+        GCMParameterSpec spec;
+        String info;
+
+        TestVector(String key, String iv, String pt, String aad,
+                   String ct, String tag) {
+            this.key = new SecretKeySpec(HexToBytes(key), "AES");
+            this.plainText = HexToBytes(pt);
+            this.aad = HexToBytes(aad);
+            this.cipherText = HexToBytes(ct);
+            this.tag = HexToBytes(tag);
+            this.spec = new GCMParameterSpec(this.tag.length * 8, HexToBytes(iv));
+            this.info = "key=" + key + ", iv=" + iv + ", pt=" + pt +
+                ",aad=" + aad + ", ct=" + ct + ", tag=" + tag;
+        }
+
+        public String toString() {
+            return info;
+        }
+    }
+
+    // These test vectors are found off NIST's CAVP page
+    // http://csrc.nist.gov/groups/STM/cavp/index.html
+    // inside the link named "GCM Test Vectors", i.e.
+    // http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
+    // CAVS 14.0, set of test vectors w/ count = 0, keysize = 128
+    private static TestVector[] testValues = {
+        // 96-bit iv w/ 128/120/112/104/96-bit tags
+        // no plain text, no aad
+        new TestVector("11754cd72aec309bf52f7687212e8957",
+                       "3c819d9a9bed087615030b65",
+                       null, null, null,
+                       "250327c674aaf477aef2675748cf6971"),
+        new TestVector("272f16edb81a7abbea887357a58c1917",
+                       "794ec588176c703d3d2a7a07",
+                       null, null, null,
+                       "b6e6f197168f5049aeda32dafbdaeb"),
+        new TestVector("81b6844aab6a568c4556a2eb7eae752f",
+                       "ce600f59618315a6829bef4d",
+                       null, null, null,
+                       "89b43e9dbc1b4f597dbbc7655bb5"),
+        new TestVector("cde2f9a9b1a004165ef9dc981f18651b",
+                       "29512c29566c7322e1e33e8e",
+                       null, null, null,
+                       "2e58ce7dabd107c82759c66a75"),
+        new TestVector("b01e45cc3088aaba9fa43d81d481823f",
+                       "5a2c4a66468713456a4bd5e1",
+                       null, null, null,
+                       "014280f944f53c681164b2ff"),
+        // 96-bit iv w/ 128/120/112/104/96-bit tags
+        // no plain text, 16-byte aad
+        new TestVector("77be63708971c4e240d1cb79e8d77feb",
+                       "e0e00f19fed7ba0136a797f3",
+                       null,
+                       "7a43ec1d9c0a5a78a0b16533a6213cab",
+                       null,
+                       "209fcc8d3675ed938e9c7166709dd946"),
+        new TestVector("da0b615656135194ba6d3c851099bc48",
+                       "d39d4b4d3cc927885090e6c3",
+                       null,
+                       "e7e5e6f8dac913036cb2ff29e8625e0e",
+                       null,
+                       "ab967711a5770461724460b07237e2"),
+        new TestVector("7e0986937a88eef894235aba4a2f43b2",
+                       "92c4a631695907166b422d60",
+                       null,
+                       "85c185f8518f9f2cd597a8f9208fc76b",
+                       null,
+                       "3bb916b728df94fe9d1916736be1"),
+        new TestVector("c3db570d7f0c21e86b028f11465d1dc9",
+                       "f86970f58ceef89fc7cb679e",
+                       null,
+                       "c095240708c0f57c288d86090ae34ee1",
+                       null,
+                       "e043c52160d652e82c7262fcf4"),
+        new TestVector("bea48ae4980d27f357611014d4486625",
+                       "32bddb5c3aa998a08556454c",
+                       null,
+                       "8a50b0b8c7654bced884f7f3afda2ead",
+                       null,
+                       "8e0f6d8bf05ffebe6f500eb1"),
+        // 96-bit iv w/ 128/120/112/104/96-bit tags
+        // no plain text, 20-byte aad
+        new TestVector("2fb45e5b8f993a2bfebc4b15b533e0b4",
+                       "5b05755f984d2b90f94b8027",
+                       null,
+                       "e85491b2202caf1d7dce03b97e09331c32473941",
+                       null,
+                       "c75b7832b2a2d9bd827412b6ef5769db"),
+        new TestVector("9bf406339fcef9675bbcf156aa1a0661",
+                       "8be4a9543d40f542abacac95",
+                       null,
+                       "7167cbf56971793186333a6685bbd58d47d379b3",
+                       null,
+                       "5e7968d7bbd5ba58cfcc750e2ef8f1"),
+        new TestVector("a2e962fff70fd0f4d63be728b80556fc",
+                       "1fa7103483de43d09bc23db4",
+                       null,
+                       "2a58edf1d53f46e4e7ee5e77ee7aeb60fc360658",
+                       null,
+                       "fa37f2dbbefab1451eae1d0d74ca"),
+        new TestVector("6bf4fdce82926dcdfc52616ed5f23695",
+                       "cc0f5899a10615567e1193ed",
+                       null,
+                       "3340655592374c1da2f05aac3ee111014986107f",
+                       null,
+                       "8ad3385cce3b5e7c985908192c"),
+        new TestVector("4df7a13e43c3d7b66b1a72fac5ba398e",
+                       "97179a3a2d417908dcf0fb28",
+                       null,
+                       "cbb7fc0010c255661e23b07dbd804b1e06ae70ac",
+                       null,
+                       "37791edae6c137ea946cfb40"),
+        // 96-bit iv w/ 128-bit tags, 13/16/32/51-byte plain text, no aad
+        new TestVector("fe9bb47deb3a61e423c2231841cfd1fb",
+                       "4d328eb776f500a2f7fb47aa",
+                       "f1cc3818e421876bb6b8bbd6c9",
+                       null,
+                       "b88c5c1977b35b517b0aeae967",
+                       "43fd4727fe5cdb4b5b42818dea7ef8c9"),
+        new TestVector("7fddb57453c241d03efbed3ac44e371c",
+                       "ee283a3fc75575e33efd4887",
+                       "d5de42b461646c255c87bd2962d3b9a2",
+                       null,
+                       "2ccda4a5415cb91e135c2a0f78c9b2fd",
+                       "b36d1df9b9d5e596f83e8b7f52971cb3"),
+        new TestVector("9971071059abc009e4f2bd69869db338",
+                       "07a9a95ea3821e9c13c63251",
+                       "f54bc3501fed4f6f6dfb5ea80106df0bd836e6826225b75c0222f6e859b35983",
+                       null,
+                       "0556c159f84ef36cb1602b4526b12009c775611bffb64dc0d9ca9297cd2c6a01",
+                       "7870d9117f54811a346970f1de090c41"),
+        new TestVector("594157ec4693202b030f33798b07176d",
+                       "49b12054082660803a1df3df",
+
+"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c",
+                      null,
+
+"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69",
+                      "ba92d3661ce8b04687e8788d55417dc2"),
+        // 96-bit iv w/ 128-bit tags, 16-byte plain text, 16/20/48/90-byte aad
+        new TestVector("c939cc13397c1d37de6ae0e1cb7c423c",
+                       "b3d8cc017cbb89b39e0f67e2",
+                       "c3b3c41f113a31b73d9a5cd432103069",
+                       "24825602bd12a984e0092d3e448eda5f",
+                       "93fe7d9e9bfd10348a5606e5cafa7354",
+                       "0032a1dc85f1c9786925a2e71d8272dd"),
+        new TestVector("d4a22488f8dd1d5c6c19a7d6ca17964c",
+                       "f3d5837f22ac1a0425e0d1d5",
+                       "7b43016a16896497fb457be6d2a54122",
+                       "f1c5d424b83f96c6ad8cb28ca0d20e475e023b5a",
+                       "c2bd67eef5e95cac27e3b06e3031d0a8",
+                       "f23eacf9d1cdf8737726c58648826e9c"),
+        new TestVector("89850dd398e1f1e28443a33d40162664",
+                       "e462c58482fe8264aeeb7231",
+                       "2805cdefb3ef6cc35cd1f169f98da81a",
+
+"d74e99d1bdaa712864eec422ac507bddbe2b0d4633cd3dff29ce5059b49fe868526c59a2a3a604457bc2afea866e7606",
+                       "ba80e244b7fc9025cd031d0f63677e06",
+                       "d84a8c3eac57d1bb0e890a8f461d1065"),
+        new TestVector("bd7c5c63b7542b56a00ebe71336a1588",
+                       "87721f23ba9c3c8ea5571abc",
+                       "de15ddbb1e202161e8a79af6a55ac6f3",
+
+"a6ec8075a0d3370eb7598918f3b93e48444751624997b899a87fa6a9939f844e008aa8b70e9f4c3b1a19d3286bf543e7127bfecba1ad17a5ec53fccc26faecacc4c75369498eaa7d706aef634d0009279b11e4ba6c993e5e9ed9",
+                       "41eb28c0fee4d762de972361c863bc80",
+                       "9cb567220d0b252eb97bff46e4b00ff8"),
+        // 8/1024-bit iv w/ 128-bit tag, no plain text, no aad
+        new TestVector("1672c3537afa82004c6b8a46f6f0d026",
+                       "05",
+                       null, null, null,
+                       "8e2ad721f9455f74d8b53d3141f27e8e"),
+        new TestVector("d0f1f4defa1e8c08b4b26d576392027c",
+
+"42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac",
+                       null, null, null,
+                       "7ab49b57ddf5f62c427950111c5c4f0d"),
+        // 8-bit iv w/ 128-bit tag, 13-byte plain text, 90-byte aad
+        new TestVector("9f79239f0904eace50784b863e723f6b",
+                       "d9",
+                       "bdb0bb10c87965acd34d146171",
+
+"44db436089327726c5f01139e1f339735c9e85514ccc2f167bad728010fb34a9072a9794c8a5e7361b1d0dbcdc9ac4091e354bb2896561f0486645252e9c78c86beece91bfa4f7cc4a8794ce1f305b1b735efdbf1ed1563c0be0",
+                       "7e5a7c8dadb3f0c7335b4d9d8d",
+                       "6b6ef1f53723a89f3bb7c6d043840717"),
+        // 1024-bit iv w/ 128-bit tag, 51-byte plain text, 48-byte aad
+        new TestVector("141f1ce91989b07e7eb6ae1dbd81ea5e",
+
+"49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e194aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e57df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470dee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea2e8f05dd3a1396f",
+
+"d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec2fe87719dadf1eb0aef212b51e74c9c5b934104a43",
+
+"630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba323951727666c947a21894a079ef061ee159c05beeb4",
+
+"f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83240446b28dc088abd42b0fc687f208190ff24c0548",
+                      "dbb93bbb56d0439cd09f620a57687f5d"),
+    };
+
+    public boolean execute(TestVector[] testValues) throws Exception {
+        boolean testFailed = false;
+        Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
+        for (int i = 0; i < testValues.length; i++) {
+            try {
+                c.init(Cipher.ENCRYPT_MODE, testValues[i].key, testValues[i].spec);
+                c.updateAAD(testValues[i].aad);
+                byte[] ctPlusTag = c.doFinal(testValues[i].plainText);
+
+                c.init(Cipher.DECRYPT_MODE, testValues[i].key, testValues[i].spec);
+                c.updateAAD(testValues[i].aad);
+                byte[] pt = c.doFinal(ctPlusTag); // should fail if tag mismatched
+
+                // check encryption/decryption results just to be sure
+                if (!Arrays.equals(testValues[i].plainText, pt)) {
+                    System.out.println("PlainText diff failed for test# " + i);
+                    testFailed = true;
+                }
+                int ctLen = testValues[i].cipherText.length;
+                if (!Arrays.equals(testValues[i].cipherText,
+                                   Arrays.copyOf(ctPlusTag, ctLen))) {
+                    System.out.println("CipherText diff failed for test# " + i);
+                    testFailed = true;
+                }
+                int tagLen = testValues[i].tag.length;
+                if (!Arrays.equals
+                    (testValues[i].tag,
+                     Arrays.copyOfRange(ctPlusTag, ctLen, ctLen+tagLen))) {
+                    System.out.println("Tag diff failed for test# " + i);
+                    testFailed = true;
+                }
+            } catch (Exception ex) {
+                // continue testing other test vectors
+                System.out.println("Failed Test Vector: " + testValues[i]);
+                ex.printStackTrace();
+                testFailed = true;
+                continue;
+            }
+        }
+        if (testFailed) {
+            throw new Exception("Test Failed");
+        }
+        // passed all tests...hooray!
+        return true;
+    }
+
+    public static void main (String[] args) throws Exception {
+        TestKATForGCM test = new TestKATForGCM();
+        if (test.execute(testValues)) {
+            System.out.println("Test Passed!");
+        }
+    }
+}
+
--- a/jdk/test/java/lang/Runtime/exec/WinCommand.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/lang/Runtime/exec/WinCommand.java	Wed Jan 16 11:58:15 2013 -0800
@@ -135,24 +135,19 @@
 
         // Win9x systems don't have a cmd.exe
         if (new File(systemDirW, "cmd.exe").exists()) {
-            try {
-                out.println("Running cmd.exe tests...");
-                writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n");
-                writeFile("cdbat.bat", "@echo off\r\nCD\r\n");
-                checkCD("cmd",
-                        "cmd.exe",
-                        systemDirW + "\\cmd.exe",
-                        // Only the ".exe" extension can be omitted
-                        systemDirW + "\\cmd",
-                        systemDirM + "/cmd.exe",
-                        systemDirM + "/cmd",
-                        "/" + systemDirM + "/cmd",
-                        "cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd",
-                        "cdbat.bat", "./cdbat.bat", ".\\cdbat.bat");
-            } finally {
-                new File("cdcmd.cmd").delete();
-                new File("cdbat.bat").delete();
-            }
+            out.println("Running cmd.exe tests...");
+            writeFile("cdcmd.cmd", "@echo off\r\nCD\r\n");
+            writeFile("cdbat.bat", "@echo off\r\nCD\r\n");
+            checkCD("cmd",
+                    "cmd.exe",
+                    systemDirW + "\\cmd.exe",
+                    // Only the ".exe" extension can be omitted
+                    systemDirW + "\\cmd",
+                    systemDirM + "/cmd.exe",
+                    systemDirM + "/cmd",
+                    "/" + systemDirM + "/cmd",
+                    "cdcmd.cmd", "./cdcmd.cmd", ".\\cdcmd.cmd",
+                    "cdbat.bat", "./cdbat.bat", ".\\cdbat.bat");
         }
 
         // 16-bit apps like command.com must have a console;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/System/MacJNUEncoding/ExpectedEncoding.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Check that the value of file.encoding and sun.jnu.encoding match the expected
+ * values passed in on the command-line.
+ */
+public class ExpectedEncoding {
+    public static void main(String[] args) {
+        boolean failed = false;
+        if (args.length != 2) {
+            System.out.println("Usage:");
+            System.out.println("$ java ExpectedEncoding <expected file.encoding> <expected sun.jnu.encoding>");
+            System.exit(1);
+        }
+        String expectFileEnc = args[0];
+        String expectSunJnuEnc = args[1];
+
+        String fileEnc = System.getProperty("file.encoding");
+        String jnuEnc = System.getProperty("sun.jnu.encoding");
+
+        if (fileEnc == null || !fileEnc.equals(expectFileEnc)) {
+            System.err.println("Expected file.encoding: " + expectFileEnc);
+            System.err.println("Actual file.encoding: " + fileEnc);
+            failed = true;
+        }
+        if (jnuEnc == null || !jnuEnc.equals(expectSunJnuEnc)) {
+            System.err.println("Expected sun.jnu.encoding: " + expectSunJnuEnc);
+            System.err.println("Actual sun.jnu.encoding: " + jnuEnc);
+            failed = true;
+        }
+        if (failed) {
+            throw new RuntimeException("Test Failed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/System/MacJNUEncoding/MacJNUEncoding.sh	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+# @test
+# @bug 8003228
+# @summary Test the value of sun.jnu.encoding on Mac
+# @author Brent Christian
+#
+# @run shell MacJNUEncoding.sh
+
+# Only run test on Mac
+OS=`uname -s`
+case "$OS" in
+  Darwin )  ;;
+  * )
+    exit 0
+    ;;
+esac
+
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+JAVAC="${TESTJAVA}"/bin/javac
+JAVA="${TESTJAVA}"/bin/java
+
+echo "Building test classes..."
+"$JAVAC" -d "${TESTCLASSES}" "${TESTSRC}"/ExpectedEncoding.java 
+
+echo ""
+echo "Running test for C locale"
+export LANG=C
+export LC_ALL=C
+"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding US-ASCII UTF-8
+result1=$?
+
+echo ""
+echo "Running test for en_US.UTF-8 locale"
+export LANG=en_US.UTF-8
+export LC_ALL=en_US.UTF-8
+"${JAVA}" ${TESTVMOPTS} -classpath "${TESTCLASSES}" ExpectedEncoding UTF-8 UTF-8
+result2=$?
+
+echo ""
+echo "Cleanup"
+rm ${TESTCLASSES}/ExpectedEncoding.class
+
+if [ ${result1} -ne 0 ] ; then
+    echo "Test failed for C locale"
+    echo "  LANG=\"${LANG}\""
+    echo "  LC_ALL=\"${LC_ALL}\""
+    exit ${result1}
+fi
+if [ ${result2} -ne 0 ] ; then
+    echo "Test failed for en_US.UTF-8 locale"
+    echo "  LANG=\"${LANG}\""
+    echo "  LC_ALL=\"${LC_ALL}\""
+    exit ${result2}
+fi
+exit 0
+
--- a/jdk/test/java/net/Socks/SocksV4Test.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/net/Socks/SocksV4Test.java	Wed Jan 16 11:58:15 2013 -0800
@@ -26,6 +26,7 @@
  * @bug 4727547
  * @summary SocksSocketImpl throws NullPointerException
  * @build SocksServer
+ * @run main SocksV4Test
  */
 
 import java.net.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/Pipe/PipeInterrupt.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8002306
+ * @summary Ensure that a Pipe can open even if its thread has already
+ *          been interrupted.
+ * @author Dan Xu
+ */
+
+import java.io.IOException;
+import java.nio.channels.Pipe;
+
+
+public class PipeInterrupt {
+
+    private Exception exc = null;
+
+    public static void main(String[] args) throws Exception {
+        PipeInterrupt instance = new PipeInterrupt();
+        instance.test();
+    }
+
+    public void test() throws Exception {
+
+        Thread tester = new Thread("PipeTester") {
+            private Pipe testPipe = null;
+
+            @Override
+            public void run() {
+                for (;;) {
+                    boolean interrupted = this.isInterrupted();
+                    try {
+                        testPipe = Pipe.open();
+                        close();
+                        if (interrupted) {
+                            if (!this.isInterrupted())
+                               exc = new RuntimeException("interrupt status reset");
+                            break;
+                        }
+                    } catch (IOException ioe) {
+                        exc = ioe;
+                    }
+                }
+            }
+
+            private void close() throws IOException {
+                if (testPipe != null) {
+                    testPipe.sink().close();
+                    testPipe.source().close();
+                }
+            }
+        };
+
+        tester.start();
+        Thread.sleep(200);
+        tester.interrupt();
+        tester.join();
+
+        if (exc != null)
+            throw exc;
+    }
+}
--- a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -168,7 +168,7 @@
             registering = null;
 
             // Need to make sure that rmid goes away by itself
-            Process rmidProcess = rmid.getVM();
+            JavaVM rmidProcess = rmid;
             if (rmidProcess != null) {
                 try {
                     Runnable waitThread =
@@ -205,9 +205,9 @@
      * class that waits for rmid to exit
      */
     private static class ShutdownDetectThread implements Runnable {
-        private Process rmidProcess = null;
+        private JavaVM rmidProcess = null;
 
-        ShutdownDetectThread(Process rmidProcess) {
+        ShutdownDetectThread(JavaVM rmidProcess) {
             this.rmidProcess = rmidProcess;
         }
         public void run() {
--- a/jdk/test/java/rmi/activation/checkusage/CheckUsage.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/activation/checkusage/CheckUsage.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 /* @test
  * @bug 4259564
+ * @summary RMID's usage message is incomplete and inconsistent with other tools
  *
  * @library ../../testlibrary
  * @build TestLibrary JavaVM
@@ -37,23 +38,16 @@
  */
 public class CheckUsage {
     public static void main(String[] args) {
-
-        System.err.println("\nregression test for 4259564\n");
-
-        JavaVM rmidVM = null;
-
         try {
-            // make sure the registry exits with a proper usage statement
             ByteArrayOutputStream berr = new ByteArrayOutputStream();
 
-            // run a VM to start the registry
-            rmidVM = new JavaVM("sun.rmi.server.Activation", "", "foo",
-                                    System.out, berr);
+            // create rmid with incorrect command line args
+            JavaVM rmidVM = new JavaVM("sun.rmi.server.Activation", "", "foo",
+                                       System.out, berr);
             System.err.println("starting rmid");
-            rmidVM.start();
 
-            // wait for registry exit
-            int rmidVMExitStatus = rmidVM.getVM().waitFor();
+            // run the subprocess and wait for it to exit
+            int rmidVMExitStatus = rmidVM.execute();
             System.err.println("rmid exited with status: " +
                                rmidVMExitStatus);
 
@@ -66,12 +60,8 @@
             } else {
                 System.err.println("test passed");
             }
-
         } catch (Exception e) {
             TestLibrary.bomb(e);
-        } finally {
-            rmidVM.destroy();
-            rmidVM = null;
         }
     }
 }
--- a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,8 +76,7 @@
             }
 
             System.err.println("starting " + utilityToStart);
-            vm.start();
-            vm.getVM().waitFor();
+            vm.execute();
 
         } catch (Exception e) {
             TestLibrary.bomb(e);
--- a/jdk/test/java/rmi/registry/checkusage/CheckUsage.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/registry/checkusage/CheckUsage.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,34 +35,21 @@
 
 /**
  * Make sure that the rmiregistry prints out a correct usage statement
- * when run with an incorrect command line; test written to conform to
- * new tighter bug fix/regression test guidelines.
+ * when run with an incorrect command line.
  */
 public class CheckUsage {
     public static void main(String[] args) {
 
-        System.err.println("\nregression test for 4151966\n");
-
-        JavaVM registryVM = null;
-
         try {
-            // make sure the registry exits with a proper usage statement
             ByteArrayOutputStream berr = new ByteArrayOutputStream();
 
             // run a VM to start the registry
-            registryVM = new JavaVM("sun.rmi.registry.RegistryImpl",
-                                    "", "foo",
-                                    System.out, berr);
+            JavaVM registryVM = new JavaVM("sun.rmi.registry.RegistryImpl",
+                                           "", "foo",
+                                           System.out, berr);
             System.err.println("starting registry");
-            registryVM.start();
-
-            // wait for registry exit
             System.err.println(" registry exited with status: " +
-                               registryVM.getVM().waitFor());
-            try {
-                Thread.sleep(7000);
-            } catch (InterruptedException ie) {
-            }
+                               registryVM.execute());
 
             String usage = new String(berr.toByteArray());
 
@@ -75,9 +62,6 @@
             }
         } catch (Exception e) {
             TestLibrary.bomb(e);
-        } finally {
-            registryVM.destroy();
-            registryVM = null;
         }
     }
 }
--- a/jdk/test/java/rmi/registry/reexport/Reexport.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/registry/reexport/Reexport.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,8 +122,7 @@
         try {
             JavaVM jvm = new JavaVM("RegistryRunner", "", Integer.toString(p));
             jvm.start();
-            Reexport.subreg = jvm.getVM();
-
+            Reexport.subreg = jvm;
         } catch (IOException e) {
             // one of these is summarily dropped, can't remember which one
             System.out.println ("Test setup failed - cannot run rmiregistry");
@@ -135,7 +134,8 @@
         } catch (Exception whatever) {
         }
     }
-    private static Process subreg = null;
+
+    private static JavaVM subreg = null;
 
     public static void killRegistry(int port) {
         if (Reexport.subreg != null) {
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,8 @@
     private OutputStream outputStream = System.out;
     private OutputStream errorStream = System.err;
     private String policyFileName = null;
+    private StreamPipe outPipe;
+    private StreamPipe errPipe;
 
     private static void mesg(Object mesg) {
         System.err.println("JAVAVM: " + mesg.toString());
@@ -145,13 +147,12 @@
         }
 
         mesg("command = " + Arrays.asList(javaCommand).toString());
-        System.err.println("");
 
         vm = Runtime.getRuntime().exec(javaCommand);
 
         /* output from the execed process may optionally be captured. */
-        StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
-        StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
+        outPipe = StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
+        errPipe = StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
     }
 
     public void destroy() {
@@ -161,7 +162,25 @@
         vm = null;
     }
 
-    protected Process getVM() {
-        return vm;
+    /**
+     * Waits for the subprocess to exit, joins the pipe threads to ensure that
+     * all output is collected, and returns its exit status.
+     */
+    public int waitFor() throws InterruptedException {
+        if (vm == null)
+            throw new IllegalStateException("can't wait for JavaVM that hasn't started");
+
+        int status = vm.waitFor();
+        outPipe.join();
+        errPipe.join();
+        return status;
+    }
+
+    /**
+     * Starts the subprocess, waits for it to exit, and returns its exit status.
+     */
+    public int execute() throws IOException, InterruptedException {
+        start();
+        return waitFor();
     }
 }
--- a/jdk/test/java/rmi/testlibrary/RMID.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/testlibrary/RMID.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -202,8 +202,6 @@
 
     public void start(long waitTime) throws IOException {
 
-        if (getVM() != null) return;
-
         // if rmid is already running, then the test will fail with
         // a well recognized exception (port already in use...).
 
--- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -114,6 +114,7 @@
                 equal = "=";
             }
 
+            // create a client to tell checkFQDN what its rmi name is.
             JavaVM jvm = new JavaVM("CheckFQDNClient",
                                     propOption + property +
                                     equal +
@@ -125,10 +126,7 @@
             propertyBeingTested=property;
             propertyBeingTestedValue=propertyValue;
 
-            // create a client to tell checkFQDN what its rmi name is. */
-            jvm.start();
-
-            if (jvm.getVM().waitFor() != 0 ) {
+            if (jvm.execute() != 0) {
                 TestLibrary.bomb("Test failed, error in client.");
             }
 
--- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -102,9 +102,8 @@
                                         " -Drmi.registry.port=" +
                                         registryPort,
                                         "");
-                jvm.start();
 
-                if (jvm.getVM().waitFor() == 1 ) {
+                if (jvm.execute() != 0) {
                     TestLibrary.bomb("Client process failed");
                 }
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Principal/Implies.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7019834
+ * @summary test default implementation of Principal.implies
+ */
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.x500.X500Principal;
+
+public class Implies {
+    public static void main(String[] args) throws Exception {
+        X500Principal duke = new X500Principal("CN=Duke");
+        // should not throw NullPointerException
+        testImplies(duke, (Subject)null, false);
+
+        Set<Principal> principals = new HashSet<>();
+        principals.add(duke);
+        testImplies(duke, principals, true);
+
+        X500Principal tux = new X500Principal("CN=Tux");
+        principals.add(tux);
+        testImplies(duke, principals, true);
+
+        principals.add(new KerberosPrincipal("duke@java.com"));
+        testImplies(duke, principals, true);
+
+        principals.clear();
+        principals.add(tux);
+        testImplies(duke, principals, false);
+
+        System.out.println("test passed");
+    }
+
+    private static void testImplies(Principal principal,
+                                    Set<? extends Principal> principals,
+                                    boolean result)
+        throws SecurityException
+    {
+        Subject subject = new Subject(true, principals, Collections.emptySet(),
+                                      Collections.emptySet());
+        testImplies(principal, subject, result);
+    }
+
+    private static void testImplies(Principal principal,
+                                    Subject subject, boolean result)
+        throws SecurityException
+    {
+        if (principal.implies(subject) != result) {
+            throw new SecurityException("test failed");
+        }
+    }
+}
--- a/jdk/test/javax/crypto/Cipher/GCMAPI.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/javax/crypto/Cipher/GCMAPI.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,6 +78,8 @@
             c.updateAAD(src);
         } catch (UnsupportedOperationException e) {
             // swallow
+        } catch (IllegalStateException ise) {
+            // swallow
         }catch (Exception e) {
             e.printStackTrace();
             failed++;
@@ -99,6 +101,8 @@
             c.updateAAD(src, offset, len);
         } catch (UnsupportedOperationException e) {
             // swallow
+        } catch (IllegalStateException ise) {
+            // swallow
         } catch (Exception e) {
             e.printStackTrace();
             failed++;
@@ -120,6 +124,8 @@
             c.updateAAD(src);
         } catch (UnsupportedOperationException e) {
             // swallow
+        } catch (IllegalStateException ise) {
+            // swallow
         }catch (Exception e) {
             e.printStackTrace();
             failed++;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/8005019/bug8005019.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8005019
+ * @summary JTable passes row index instead of length when inserts selection interval
+ * @author Alexander Scherbatiy
+ * @run main bug8005019
+ */
+
+import java.util.*;
+import javax.swing.*;
+import javax.swing.table.*;
+
+public class bug8005019 {
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                testSelectionWithFilterTable();
+            }
+        });
+    }
+
+    private static void testSelectionWithFilterTable() {
+        DefaultTableModel model = new DefaultTableModel(0, 1);
+        // a model with 3 elements is the minimum to demonstrate
+        // the bug
+        int last = 2;
+        for (int i = 0; i <= last; i++) {
+            model.addRow(new Object[]{i});
+        }
+        JTable table = new JTable(model);
+        table.setAutoCreateRowSorter(true);
+        // set selection at the end
+        table.setRowSelectionInterval(last, last);
+        // exclude rows based on identifier
+        RowFilter filter = new GeneralFilter(new int[]{0});
+        ((DefaultRowSorter) table.getRowSorter()).setRowFilter(filter);
+        // insertRow _before or at_ selected model index, such that
+        // endIndex (in event) > 1
+        model.insertRow(2, new Object[]{"x"});
+    }
+
+    private static class GeneralFilter extends RowFilter<Object, Object> {
+
+        private int[] columns;
+        List excludes = Arrays.asList(0);
+
+        GeneralFilter(int[] columns) {
+            this.columns = columns;
+        }
+
+        public boolean include(RowFilter.Entry<? extends Object, ? extends Object> value) {
+            int count = value.getValueCount();
+            if (columns.length > 0) {
+                for (int i = columns.length - 1; i >= 0; i--) {
+                    int index = columns[i];
+                    if (index < count) {
+                        if (include(value, index)) {
+                            return true;
+                        }
+                    }
+                }
+            } else {
+                while (--count >= 0) {
+                    if (include(value, count)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        protected boolean include(
+                Entry<? extends Object, ? extends Object> entry,
+                int index) {
+            return !excludes.contains(entry.getIdentifier());
+        }
+    }
+}
--- a/jdk/test/sun/rmi/runtime/Log/4504153/Test4504153.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/rmi/runtime/Log/4504153/Test4504153.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,8 +48,7 @@
         ByteArrayOutputStream err = new ByteArrayOutputStream();
         JavaVM vm = new JavaVM(StartRegistry.class.getName(),
                                "-Dsun.rmi.transport.logLevel=v", "", out, err);
-        vm.start();
-        vm.getVM().waitFor();
+        vm.execute();
 
         String errString = err.toString();
 
--- a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,8 +65,7 @@
         JavaVM vm = new JavaVM(DoRMIStuff.class.getName(),
             "-Djava.util.logging.config.file=" + loggingPropertiesFile,
                                "", out, err);
-        vm.start();
-        vm.getVM().waitFor();
+        vm.execute();
 
         /*
          * Verify that the subprocess had no System.out or System.err
--- a/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,7 +104,7 @@
             JavaVM jvm =
                 new JavaVM("sun.rmi.registry.RegistryImpl", "", Integer.toString(p));
             jvm.start();
-            DeadCachedConnection.subreg = jvm.getVM();
+            DeadCachedConnection.subreg = jvm;
 
         } catch (IOException e) {
             // one of these is summarily dropped, can't remember which one
@@ -117,7 +117,7 @@
         } catch (Exception whatever) {
         }
     }
-    private static Process subreg = null;
+    private static JavaVM subreg = null;
 
     public static void killRegistry() {
         if (DeadCachedConnection.subreg != null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/ServiceCredsCombination.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 8005447
+ * @compile -XDignore.symbol.file ServiceCredsCombination.java
+ * @run main ServiceCredsCombination
+ * @summary default principal can act as anyone
+ */
+
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Objects;
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosKey;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.kerberos.KeyTab;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import sun.security.jgss.GSSUtil;
+
+public class ServiceCredsCombination {
+
+    public static void main(String[] args) throws Exception {
+        // pass
+        check("a", "a", princ("a"), key("a"));
+        check(null, "a", princ("a"), key("a"));
+        check("x", "NOCRED", princ("a"), key("a"));
+        // two pass
+        check("a", "a", princ("a"), key("a"), princ("b"), key("b"));
+        check("b", "b", princ("a"), key("a"), princ("b"), key("b"));
+        check(null, null, princ("a"), key("a"), princ("b"), key("b"));
+        check("x", "NOCRED", princ("a"), key("a"), princ("b"), key("b"));
+        // old ktab
+        check("b", "b", princ("b"), oldktab());
+        check("x", "NOCRED", princ("b"), oldktab());
+        check(null, "b", princ("b"), oldktab());
+        // Two old ktab
+        check("a", "a", princ("a"), princ("b"), oldktab(), oldktab());
+        check("b", "b", princ("a"), princ("b"), oldktab(), oldktab());
+        check(null, null, princ("a"), princ("b"), oldktab(), oldktab());
+        check("x", "NOCRED", princ("a"), princ("b"), oldktab(), oldktab());
+        // pass + old ktab
+        check("a", "a", princ("a"), princ("b"), key("a"), oldktab());
+        check("b", "b", princ("a"), princ("b"), key("a"), oldktab());
+        check(null, null, princ("a"), princ("b"), key("a"), oldktab());
+        check("x", "NOCRED", princ("a"), princ("b"), key("a"), oldktab());
+        // Compatibility, automatically add princ for keys
+        check(null, "a", key("a"));
+        check("x", "NOCRED", key("a"));
+        check(null, "a", key("a"), oldktab());
+        check("x", "NOCRED", key("a"), oldktab());
+        // Limitation, "a" has no key, but we don't know oldktab() is for "b"
+        check("a", "a", princ("a"), princ("b"), oldktab());
+    }
+
+    /**
+     * Checks the correct bound
+     * @param a get a creds for this principal, null for default one
+     * @param b expected name, null for still unbound, "NOCRED" for no creds
+     * @param objs princs, keys and keytabs in the subject
+     */
+    private static void check(final String a, String b, Object... objs)
+            throws Exception {
+        Subject subj = new Subject();
+        for (Object obj: objs) {
+            if (obj instanceof KerberosPrincipal) {
+                subj.getPrincipals().add((KerberosPrincipal)obj);
+            } else if (obj instanceof KerberosKey || obj instanceof KeyTab) {
+                subj.getPrivateCredentials().add(obj);
+            }
+        }
+        final GSSManager man = GSSManager.getInstance();
+        try {
+            String result = Subject.doAs(
+                    subj, new PrivilegedExceptionAction<String>() {
+                @Override
+                public String run() throws GSSException {
+                    GSSCredential cred = man.createCredential(
+                            a == null ? null : man.createName(r(a), null),
+                            GSSCredential.INDEFINITE_LIFETIME,
+                            GSSUtil.GSS_KRB5_MECH_OID,
+                            GSSCredential.ACCEPT_ONLY);
+                    GSSName name = cred.getName();
+                    return name == null ? null : name.toString();
+                }
+            });
+            if (!Objects.equals(result, r(b))) {
+                throw new Exception("Check failed: getInstance(" + a
+                        + ") has name " + result + ", not " + b);
+            }
+        } catch (PrivilegedActionException e) {
+            if (!"NOCRED".equals(b)) {
+                throw new Exception("Check failed: getInstance(" + a
+                        + ") is null " + ", but not one with name " + b);
+            }
+        }
+    }
+    private static String r(String s) {
+        return s == null ? null : (s+"@REALM");
+    }
+    private static KerberosPrincipal princ(String s) {
+        return new KerberosPrincipal(r(s));
+    }
+    private static KerberosKey key(String s) {
+        return new KerberosKey(princ(s), new byte[0], 0, 0);
+    }
+    private static KeyTab oldktab() {
+        return KeyTab.getInstance();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/AcceptPermissions.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 9999999
+ * @summary default principal can act as anyone
+ * @compile -XDignore.symbol.file AcceptPermissions.java
+ * @run main/othervm AcceptPermissions
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.security.Permission;
+import javax.security.auth.kerberos.ServicePermission;
+import sun.security.jgss.GSSUtil;
+import java.util.*;
+
+public class AcceptPermissions extends SecurityManager {
+
+    private static Map<Permission,String> perms = new HashMap<>();
+    @Override
+    public void checkPermission(Permission perm) {
+        if (!(perm instanceof ServicePermission)) {
+            return;
+        }
+        ServicePermission sp = (ServicePermission)perm;
+        if (!sp.getActions().equals("accept")) {
+            return;
+        }
+        // We only care about accept ServicePermission in this test
+        try {
+            super.checkPermission(sp);
+        } catch (SecurityException se) {
+            if (perms.containsKey(sp)) {
+                perms.put(sp, "checked");
+            } else {
+                throw se;   // We didn't expect this is needed
+            }
+        }
+    }
+
+    // Fills in permissions we are expecting
+    private static void initPerms(String... names) {
+        perms.clear();
+        for (String name: names) {
+            perms.put(new ServicePermission(
+                    name + "@" + OneKDC.REALM, "accept"), "expected");
+        }
+    }
+
+    // Checks if they are all checked
+    private static void checkPerms() {
+        for (Map.Entry<Permission,String> entry: perms.entrySet()) {
+            if (entry.getValue().equals("expected")) {
+                throw new RuntimeException(
+                        "Expected but not used: " + entry.getKey());
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        System.setSecurityManager(new AcceptPermissions());
+        new OneKDC(null).writeJAASConf();
+        String two = "two {\n"
+                + " com.sun.security.auth.module.Krb5LoginModule required"
+                + "     principal=\"" + OneKDC.SERVER + "\" useKeyTab=true"
+                + "     isInitiator=false storeKey=true;\n"
+                + " com.sun.security.auth.module.Krb5LoginModule required"
+                + "     principal=\"" + OneKDC.BACKEND + "\" useKeyTab=true"
+                + "     isInitiator=false storeKey=true;\n"
+                + "};\n";
+        Files.write(Paths.get(OneKDC.JAAS_CONF), two.getBytes(),
+                StandardOpenOption.APPEND);
+
+        Context c, s;
+
+        // In all cases, a ServicePermission on the acceptor name is needed
+        // for a handshake. For default principal with no predictable name,
+        // permission not needed (yet) for credentials creation.
+
+        // Named principal
+        initPerms(OneKDC.SERVER);
+        c = Context.fromJAAS("client");
+        s = Context.fromJAAS("server");
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        checkPerms();
+        initPerms(OneKDC.SERVER);
+        Context.handshake(c, s);
+        checkPerms();
+
+        // Named principal (even if there are 2 JAAS modules)
+        initPerms(OneKDC.SERVER);
+        c = Context.fromJAAS("client");
+        s = Context.fromJAAS("two");
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        checkPerms();
+        initPerms(OneKDC.SERVER);
+        Context.handshake(c, s);
+        checkPerms();
+
+        // Default principal with a predictable name
+        initPerms(OneKDC.SERVER);
+        c = Context.fromJAAS("client");
+        s = Context.fromJAAS("server");
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+        checkPerms();
+        initPerms(OneKDC.SERVER);
+        Context.handshake(c, s);
+        checkPerms();
+
+        // Default principal with no predictable name
+        initPerms();    // permission not needed for cred !!!
+        c = Context.fromJAAS("client");
+        s = Context.fromJAAS("two");
+        c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(GSSUtil.GSS_KRB5_MECH_OID);
+        checkPerms();
+        initPerms(OneKDC.SERVER);   // still needed for handshake !!!
+        Context.handshake(c, s);
+        checkPerms();
+    }
+}
--- a/jdk/test/sun/security/krb5/auto/CleanState.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/security/krb5/auto/CleanState.java	Wed Jan 16 11:58:15 2013 -0800
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 6716534
+ * @compile -XDignore.symbol.file CleanState.java
  * @run main/othervm CleanState
  * @summary Krb5LoginModule has not cleaned temp info between authentication attempts
  */
--- a/jdk/test/sun/security/krb5/auto/Context.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/security/krb5/auto/Context.java	Wed Jan 16 11:58:15 2013 -0800
@@ -131,21 +131,24 @@
         return out;
     }
 
+    /**
+     * Logins with username/password as a new Subject
+     */
     public static Context fromUserPass(
             String user, char[] pass, boolean storeKey) throws Exception {
-        return fromUserPass(null, user, pass, storeKey);
+        return fromUserPass(new Subject(), user, pass, storeKey);
     }
 
     /**
-     * Logins with a username and a password, using Krb5LoginModule directly
-     * @param s existing subject, test multiple princ & creds for single subj
-     * @param storeKey true if key should be saved, used on acceptor side
+     * Logins with username/password as an existing Subject. The
+     * same subject can be used multiple times to simulate multiple logins.
+     * @param s existing subject
      */
     public static Context fromUserPass(Subject s,
             String user, char[] pass, boolean storeKey) throws Exception {
         Context out = new Context();
         out.name = user;
-        out.s = s == null ? new Subject() : s;
+        out.s = s;
         Krb5LoginModule krb5 = new Krb5LoginModule();
         Map<String, String> map = new HashMap<>();
         Map<String, Object> shared = new HashMap<>();
@@ -172,14 +175,23 @@
     }
 
     /**
-     * Logins with a username and a keytab, using Krb5LoginModule directly
-     * @param storeKey true if key should be saved, used on acceptor side
+     * Logins with username/keytab as an existing Subject. The
+     * same subject can be used multiple times to simulate multiple logins.
+     * @param s existing subject
      */
-    public static Context fromUserKtab(String user, String ktab, boolean storeKey)
-            throws Exception {
+    public static Context fromUserKtab(
+            String user, String ktab, boolean storeKey) throws Exception {
+        return fromUserKtab(new Subject(), user, ktab, storeKey);
+    }
+
+    /**
+     * Logins with username/keytab as a new subject,
+     */
+    public static Context fromUserKtab(Subject s,
+            String user, String ktab, boolean storeKey) throws Exception {
         Context out = new Context();
         out.name = user;
-        out.s = new Subject();
+        out.s = s;
         Krb5LoginModule krb5 = new Krb5LoginModule();
         Map<String, String> map = new HashMap<>();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/DiffNameSameKey.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005447
+ * @summary default principal can act as anyone
+ * @compile -XDignore.symbol.file DiffNameSameKey.java
+ * @run main/othervm/fail DiffNameSameKey a
+ * @run main/othervm DiffNameSameKey b
+ */
+
+import sun.security.jgss.GSSUtil;
+import sun.security.krb5.PrincipalName;
+
+/**
+ * This test confirms the compatibility codes described in
+ * ServiceCreds.getEKeys(). If the acceptor starts as x.us.oracle.com
+ * but client requests for x.us, as long as the KDC supports both names
+ * and the keys are the same, the auth should succeed.
+ */
+public class DiffNameSameKey {
+
+    static final String SERVER2 = "x" + OneKDC.SERVER;
+
+    public static void main(String[] args) throws Exception {
+
+        OneKDC kdc = new KDC2();
+        kdc.addPrincipal(SERVER2, "samepass".toCharArray());
+        kdc.addPrincipal(OneKDC.SERVER, "samepass".toCharArray());
+        kdc.writeJAASConf();
+        kdc.writeKtab(OneKDC.KTAB);
+
+        Context c, s;
+        c = Context.fromJAAS("client");
+        s = Context.fromJAAS("server");
+
+        switch (args[0]) {
+            case "a":   // If server starts as another service, should fail
+                c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_SPNEGO_MECH_OID);
+                s.startAsServer(SERVER2.replace('/', '@'),
+                        GSSUtil.GSS_SPNEGO_MECH_OID);
+                break;
+            case "b":   // If client requests another server with the same keys,
+                        // succeed to be compatible
+                c.startAsClient(SERVER2, GSSUtil.GSS_SPNEGO_MECH_OID);
+                s.startAsServer(OneKDC.SERVER.replace('/', '@'),
+                        GSSUtil.GSS_SPNEGO_MECH_OID);
+                break;
+        }
+
+        Context.handshake(c, s);
+
+        s.dispose();
+        c.dispose();
+    }
+
+    /**
+     * This KDC returns the same salt for all principals. This means same
+     * passwords generate same keys.
+     */
+    static class KDC2 extends OneKDC {
+        KDC2() throws Exception {
+            super(null);
+        }
+        @Override
+        public String getSalt(PrincipalName pn) {
+            return "SAME";
+        }
+    }
+}
--- a/jdk/test/sun/security/krb5/auto/DynamicKeytab.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/security/krb5/auto/DynamicKeytab.java	Wed Jan 16 11:58:15 2013 -0800
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 6894072
+ * @compile -XDignore.symbol.file DynamicKeytab.java
  * @run main/othervm DynamicKeytab
  * @summary always refresh keytab
  */
--- a/jdk/test/sun/security/krb5/auto/KDC.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/security/krb5/auto/KDC.java	Wed Jan 16 11:58:15 2013 -0800
@@ -285,10 +285,12 @@
             if (Character.isDigit(pass[pass.length-1])) {
                 kvno = pass[pass.length-1] - '0';
             }
-            ktab.addEntry(new PrincipalName(name,
-                    name.indexOf('/') < 0 ?
-                        PrincipalName.KRB_NT_UNKNOWN :
-                        PrincipalName.KRB_NT_SRV_HST),
+            PrincipalName pn = new PrincipalName(name,
+                        name.indexOf('/') < 0 ?
+                            PrincipalName.KRB_NT_UNKNOWN :
+                            PrincipalName.KRB_NT_SRV_HST);
+            ktab.addEntry(pn,
+                        getSalt(pn),
                         pass,
                         kvno,
                         true);
@@ -534,7 +536,7 @@
         if (pass == null) {
             throw new KrbException(server?
                 Krb5.KDC_ERR_S_PRINCIPAL_UNKNOWN:
-                Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN);
+                Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN, pn.toString());
         }
         return pass;
     }
@@ -544,7 +546,7 @@
      * @param p principal
      * @return the salt
      */
-    private String getSalt(PrincipalName p) {
+    protected String getSalt(PrincipalName p) {
         String pn = p.toString();
         if (p.getRealmString() == null) {
             pn = pn + "@" + getRealm();
--- a/jdk/test/sun/security/krb5/auto/KeyTabCompat.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/security/krb5/auto/KeyTabCompat.java	Wed Jan 16 11:58:15 2013 -0800
@@ -38,7 +38,7 @@
  *
  * 1. If there is only KerberosKeys in private credential set and no
  *    KerberosPrincipal. JAAS login should go on.
- * 2. Even if KeyTab is used, user can still get KerberosKeys from
+ * 2. If KeyTab is used, user won't get KerberosKeys from
  *    private credentials set.
  */
 public class KeyTabCompat {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/TwoOrThree.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005447
+ * @summary default principal can act as anyone
+ * @compile -XDignore.symbol.file TwoOrThree.java
+ * @run main/othervm TwoOrThree first first
+ * @run main/othervm/fail TwoOrThree first second
+ * @run main/othervm TwoOrThree - first
+ * @run main/othervm TwoOrThree - second
+ * @run main/othervm/fail TwoOrThree - third
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import javax.security.auth.Subject;
+import sun.security.jgss.GSSUtil;
+
+/*
+ * The JAAS login has two krb5 modules
+ *   1. principal is A
+ *   2. principal is B
+ * A named principal can only accept itself. The default principal can accept
+ * either, but not any other service even if the keytab also include its keys.
+ */
+public class TwoOrThree {
+
+    public static void main(String[] args) throws Exception {
+
+        String server = args[0].equals("-") ? null : args[0];
+        String target = args[1];
+        OneKDC kdc = new OneKDC(null);
+        kdc.addPrincipal("first", "first".toCharArray());
+        kdc.addPrincipal("second", "second".toCharArray());
+        kdc.addPrincipal("third", "third".toCharArray());
+        kdc.writeKtab(OneKDC.KTAB);
+
+        Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+
+        // Using keytabs
+        Subject sub4s = new Subject();
+        Context.fromUserKtab(sub4s, "first", OneKDC.KTAB, true);
+        Context s = Context.fromUserKtab(sub4s, "second", OneKDC.KTAB, true);
+        c.startAsClient(target, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(server, GSSUtil.GSS_KRB5_MECH_OID);
+        Context.handshake(c, s);
+
+        // Using keys
+        sub4s = new Subject();
+        Context.fromUserPass(sub4s, "first", "first".toCharArray(), true);
+        s = Context.fromUserPass(sub4s, "second", "second".toCharArray(), true);
+        c.startAsClient(target, GSSUtil.GSS_KRB5_MECH_OID);
+        s.startAsServer(server, GSSUtil.GSS_KRB5_MECH_OID);
+        Context.handshake(c, s);
+
+        s.dispose();
+        c.dispose();
+    }
+}
--- a/jdk/test/sun/security/provider/PolicyFile/Comparator.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/sun/security/provider/PolicyFile/Comparator.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,6 @@
 import javax.security.auth.x500.X500Principal;
 
 import sun.security.provider.PolicyFile;
-import com.sun.security.auth.PrincipalComparator;
 import com.sun.security.auth.UnixPrincipal;
 import com.sun.security.auth.NTUserPrincipal;
 import com.sun.security.auth.SolarisPrincipal;
@@ -90,7 +89,7 @@
     private static final Principal[] badP = new Principal[] {
                                 new SolarisPrincipal("bad") };
 
-    public static class PCompare1 implements PrincipalComparator {
+    public static class PCompare1 implements Principal {
 
         private String name;
 
@@ -98,6 +97,12 @@
             this.name = name;
         }
 
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
         public boolean implies (Subject subject) {
             if (subject.getPrincipals().contains(p1[0])) {
                 return true;
@@ -106,13 +111,19 @@
         }
     }
 
-    public static class PCompare2 implements PrincipalComparator {
+    public static class PCompare2 implements Principal {
         private String name;
 
         public PCompare2(String name) {
             this.name = name;
         }
 
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
         public boolean implies (Subject subject) {
             if (subject.getPrincipals().contains(p2[0]) &&
                 subject.getPrincipals().contains(p2[1])) {
@@ -122,13 +133,19 @@
         }
     }
 
-    public static class PCompare3 implements PrincipalComparator {
+    public static class PCompare3 implements Principal {
         private String name;
 
         public PCompare3(String name) {
             this.name = name;
         }
 
+        @Override
+        public String getName() {
+            return name;
+        }
+
+        @Override
         public boolean implies (Subject subject) {
             return false;
         }
--- a/jdk/test/tools/launcher/FXLauncherTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/tools/launcher/FXLauncherTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8001533
+ * @bug 8001533 8004547
  * @summary Test launching FX application with java -jar
  * Test uses main method and blank main method, a jfx app class and an incorrest
  * jfx app class, a main-class for the manifest, a bogus one and none.
@@ -47,6 +47,8 @@
 
     /* standard main class can be used as java main for fx app class */
     static final String StdMainClass = "helloworld.HelloWorld";
+    static final String ExtMainClass = "helloworld.ExtHello";
+    static final String NonFXMainClass = "helloworld.HelloJava";
     static int testcount = 0;
 
     /* a main method and a blank. */
@@ -107,9 +109,7 @@
     }
 
     /*
-     * Create class to extend fx java file for test application
-     * TODO: make test to create java file and this extension of the java file
-     *      and jar them together an run app via this java class.
+     * Create class that extends HelloWorld instead of Application
      */
     static void createExtJavaFile(String mainmethod) {
         try {
@@ -125,16 +125,48 @@
             compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
         } catch (java.io.IOException ioe) {
             ioe.printStackTrace();
-            throw new RuntimeException("Failed creating HelloWorld.");
+            throw new RuntimeException("Failed creating ExtHello.");
+        }
+    }
+
+    /*
+     * Create non-JavaFX class for testing if jfxrt.jar is being loaded
+     * when it shouldn't be
+     */
+    static void createNonFXJavaFile() {
+        try {
+            String mainClass = "HelloJava";
+            List<String> contents = new ArrayList<>();
+            contents.add("package helloworld;");
+            contents.add("public class HelloJava {");
+            contents.add("    public static void main(String[] args) {");
+            contents.add("        for(String aa : args)");
+            contents.add("            System.out.println(\"arg: \" + aa);" );
+            contents.add("    }");
+            contents.add("}");
+            // Create and compile java source.
+            MainJavaFile = new File(mainClass + JAVA_FILE_EXT);
+            createFile(MainJavaFile, contents);
+            compile("-cp", ".", "-d", ".", mainClass + JAVA_FILE_EXT);
+        } catch (java.io.IOException ioe) {
+            ioe.printStackTrace();
+            throw new RuntimeException("Failed creating HelloJava.");
         }
     }
 
     // Create manifest for test fx application
-    static List<String> createManifestContents(String mainclassentry) {
+    static List<String> createManifestContents(String mainClassEntry, String fxMainEntry) {
         List<String> mcontents = new ArrayList<>();
         mcontents.add("Manifest-Version: 1.0");
         mcontents.add("Created-By: FXLauncherTest");
-        mcontents.add("Main-Class: " + mainclassentry);
+        if (mainClassEntry != null) {
+            mcontents.add("Main-Class: " + mainClassEntry);
+            System.out.println("Main-Class: " + mainClassEntry);
+        }
+        if (fxMainEntry != null) {
+            mcontents.add("JavaFX-Application-Class: " + fxMainEntry);
+            System.out.println("JavaFX-Application-Class: " + fxMainEntry);
+        }
         return mcontents;
     }
 
@@ -175,31 +207,41 @@
 
     /*
      * Set Main-Class and iterate main_methods.
-     * Try launching with both -jar and -cp methods.
+     * Try launching with both -jar and -cp methods, with and without FX main
+     * class manifest entry.
      * All cases should run.
+     *
+     * See sun.launcher.LauncherHelper$FXHelper for more details on how JavaFX
+     * applications are launched.
      */
     @Test
     static void testBasicFXApp() throws Exception {
-        testBasicFXApp(true);
-        testBasicFXApp(false);
+        testBasicFXApp(true, false);    // -cp, no JAC
+        testBasicFXApp(false, true);    // -jar, with JAC
+        testBasicFXApp(false, false);   // -jar, no JAC
     }
 
-    static void testBasicFXApp(boolean useCP) throws Exception {
+    static void testBasicFXApp(boolean useCP, boolean setFXMainClass) throws Exception {
         String testname = "testBasicFXApp";
+        if (useCP) {
+            testname = testname.concat("_useCP");
+        }
+        String fxMC = StdMainClass;
+        if (!setFXMainClass) {
+            testname = testname.concat("_noJAC");
+            fxMC = null;
+        }
         for (String mm : MAIN_METHODS) {
             testcount++;
             line();
-            System.out.println("test# " + testcount +
-                "-  Main method: " + mm +
-                 ";  MF main class: " + StdMainClass);
+            System.out.println("test# " + testcount + "-  Main method: " + mm);
             createJavaFile(mm);
-            createFile(ManifestFile, createManifestContents(StdMainClass));
+            createFile(ManifestFile, createManifestContents(StdMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
             TestResult tr;
             if (useCP) {
                 tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
-                testname = testname.concat("_useCP");
             } else {
                 tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
             }
@@ -224,26 +266,33 @@
      */
     @Test
     static void testExtendFXApp() throws Exception {
-        testExtendFXApp(true);
-        testExtendFXApp(false);
+        testExtendFXApp(true, false);   // -cp, no JAC
+        testExtendFXApp(false, true);   // -jar, with JAC
+        testExtendFXApp(false, false);  // -jar, no JAC
     }
 
-    static void testExtendFXApp(boolean useCP) throws Exception {
+    static void testExtendFXApp(boolean useCP, boolean setFXMainClass) throws Exception {
         String testname = "testExtendFXApp";
+        if (useCP) {
+            testname = testname.concat("_useCP");
+        }
+        String fxMC = ExtMainClass;
+        if (!setFXMainClass) {
+            testname = testname.concat("_noJAC");
+            fxMC = null;
+        }
         for (String mm : MAIN_METHODS) {
             testcount++;
             line();
-            System.out.println("test# " + testcount +
-                "-  Main method: " + mm + ";  MF main class: " + StdMainClass);
+            System.out.println("test# " + testcount + "-  Main method: " + mm);
             createJavaFile(mm);
             createExtJavaFile(mm);
-            createFile(ManifestFile, createManifestContents(StdMainClass));
+            createFile(ManifestFile, createManifestContents(ExtMainClass, fxMC));
             createJar(FXtestJar, ManifestFile);
             String sTestJar = FXtestJar.getAbsolutePath();
             TestResult tr;
             if (useCP) {
-                tr = doExec(javaCmd, "-cp", sTestJar, StdMainClass, APP_PARMS[0], APP_PARMS[1]);
-                testname = testname.concat("_useCP");
+                tr = doExec(javaCmd, "-cp", sTestJar, ExtMainClass, APP_PARMS[0], APP_PARMS[1]);
             } else {
                 tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
             }
@@ -256,27 +305,82 @@
                     }
                 }
             }
-            checkStatus(tr, testname, testcount, StdMainClass);
+            checkStatus(tr, testname, testcount, ExtMainClass);
         }
     }
 
     /*
+     * Ensure we can NOT launch a FX app jar with no Main-Class manifest entry
+     */
+    @Test
+    static void testMissingMC() throws Exception {
+        String testname = "testMissingMC";
+        testcount++;
+        line();
+        System.out.println("test# " + testcount + ": abort on missing Main-Class");
+        createJavaFile(" "); // no main() needed
+        createFile(ManifestFile, createManifestContents(null, StdMainClass)); // No MC, but supply JAC
+        createJar(FXtestJar, ManifestFile);
+        String sTestJar = FXtestJar.getAbsolutePath();
+        TestResult tr = doExec(javaCmd, "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
+        tr.checkNegative(); // should abort if no Main-Class
+        if (tr.testStatus) {
+            if (!tr.contains("no main manifest attribute")) {
+                System.err.println("ERROR: launcher did not abort properly");
+            }
+        } else {
+            System.err.println("ERROR: jar executed with no Main-Class!");
+        }
+        checkStatus(tr, testname, testcount, StdMainClass);
+    }
+
+    /*
      * test to ensure that we don't load any extraneous fx jars when
      * launching a standard java application
+     * Test both -cp and -jar methods since they use different code paths.
+     * Neither case should cause jfxrt.jar to be loaded.
      */
     @Test
-    static void testExtraneousJars()throws Exception {
+    static void testExtraneousJars() throws Exception {
+        testExtraneousJars(true);
+        testExtraneousJars(false);
+    }
+
+    static void testExtraneousJars(boolean useCP) throws Exception {
         String testname = "testExtraneousJars";
+        if (useCP) {
+            testname = testname.concat("_useCP");
+        }
         testcount++;
         line();
-        System.out.println("test# " + testcount);
-        TestResult tr = doExec(javacCmd, "-J-verbose:class", "-version");
-        if (!tr.notContains("jfxrt.jar")) {
-            System.out.println("testing for extraneous jfxrt jar");
-            System.out.println(tr);
-            throw new Exception("jfxrt.jar is being loaded by javac!!!");
+        System.out.println("test# " + testcount
+                + ": test for erroneous jfxrt.jar loading");
+        createNonFXJavaFile();
+        createFile(ManifestFile, createManifestContents(NonFXMainClass, null));
+        createJar(FXtestJar, ManifestFile);
+        String sTestJar = FXtestJar.getAbsolutePath();
+        TestResult tr;
+
+        if (useCP) {
+            tr = doExec(javaCmd, "-verbose:class", "-cp", sTestJar, NonFXMainClass, APP_PARMS[0], APP_PARMS[1]);
+        } else {
+            tr = doExec(javaCmd, "-verbose:class", "-jar", sTestJar, APP_PARMS[0], APP_PARMS[1]);
         }
-        checkStatus(tr, testname, testcount, StdMainClass);
+        tr.checkPositive();
+        if (tr.testStatus) {
+            if (!tr.notContains("jfxrt.jar")) {
+                System.out.println("testing for extraneous jfxrt jar");
+                System.out.println(tr);
+                throw new Exception("jfxrt.jar is being loaded, it should not be!");
+            }
+            for (String p : APP_PARMS) {
+                if (!tr.contains(p)) {
+                    System.err.println("ERROR: Did not find "
+                            + p + " in output!");
+                }
+            }
+        }
+        checkStatus(tr, testname, testcount, NonFXMainClass);
     }
 
     public static void main(String... args) throws Exception {
--- a/jdk/test/tools/launcher/VersionCheck.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/jdk/test/tools/launcher/VersionCheck.java	Wed Jan 16 11:58:15 2013 -0800
@@ -68,6 +68,7 @@
         "jcmd",
         "jconsole",
         "jcontrol",
+        "jdeps",
         "jinfo",
         "jmap",
         "jps",
--- a/langtools/.hgtags	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/.hgtags	Wed Jan 16 11:58:15 2013 -0800
@@ -192,3 +192,5 @@
 014a6a11dfe5ddc23ec8c76bb42ac998dbf49acb jdk8-b68
 d7360bf35ee1f40ff78c2e83a22b5446ee464346 jdk8-b69
 47f71d7c124f24c2fe2dfc49865b332345b458ed jdk8-b70
+467e4d9281bcf119eaec42af1423c96bd401871c jdk8-b71
+6f0986ed9b7e11d6eb06618f27e20b18f19fb797 jdk8-b72
--- a/langtools/make/build.properties	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/make/build.properties	Wed Jan 16 11:58:15 2013 -0800
@@ -153,6 +153,7 @@
 javap.includes = \
         com/sun/tools/classfile/ \
         com/sun/tools/javap/ \
+        com/sun/tools/jdeps/ \
         sun/tools/javap/
 
 javap.tests = \
--- a/langtools/makefiles/BuildLangtools.gmk	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/makefiles/BuildLangtools.gmk	Wed Jan 16 11:58:15 2013 -0800
@@ -75,6 +75,7 @@
 	printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javah/resources/version.properties
 	printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javap/resources/version.properties
 	printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javac/resources/version.properties
+	printf "jdk=$(JDK_VERSION)\nfull=$(FULL_VERSION)\nrelease=$(RELEASE)\n" > $(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/jdeps/resources/version.properties
 	echo Compiling $(words $(PROPSOURCES) v1 v2 v3) properties into resource bundles
 	$(TOOL_COMPILEPROPS_CMD) $(PROPCMDLINE) \
 		-compile 	$(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javah/resources/version.properties \
@@ -85,6 +86,9 @@
 				java.util.ListResourceBundle \
 		-compile	$(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javac/resources/version.properties \
 				$(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/javac/resources/version.java \
+				java.util.ListResourceBundle \
+		-compile	$(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/jdeps/resources/version.properties \
+				$(LANGTOOLS_OUTPUTDIR)/gensrc/com/sun/tools/jdeps/resources/version.java \
 				java.util.ListResourceBundle
 	echo PROPS_ARE_CREATED=yes > $@
 
--- a/langtools/src/share/classes/com/sun/javadoc/AnnotationDesc.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/javadoc/AnnotationDesc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -52,6 +52,12 @@
      */
     ElementValuePair[] elementValues();
 
+    /**
+     * Check for the synthesized bit on the annotation.
+     *
+     * @return true if the annotation is synthesized.
+     */
+    boolean isSynthesized();
 
     /**
      * Represents an association between an annotation type element
--- a/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Attribute.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,7 @@
     public static final String LineNumberTable          = "LineNumberTable";
     public static final String LocalVariableTable       = "LocalVariableTable";
     public static final String LocalVariableTypeTable   = "LocalVariableTypeTable";
+    public static final String MethodParameters         = "MethodParameters";
     public static final String RuntimeVisibleAnnotations = "RuntimeVisibleAnnotations";
     public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
     public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
@@ -113,6 +114,7 @@
             standardAttributes.put(LocalVariableTypeTable, LocalVariableTypeTable_attribute.class);
 
             if (!compat) { // old javap does not recognize recent attributes
+                standardAttributes.put(MethodParameters, MethodParameters_attribute.class);
                 standardAttributes.put(CompilationID, CompilationID_attribute.class);
                 standardAttributes.put(RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations_attribute.class);
                 standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
@@ -171,6 +173,7 @@
         R visitLineNumberTable(LineNumberTable_attribute attr, P p);
         R visitLocalVariableTable(LocalVariableTable_attribute attr, P p);
         R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p);
+        R visitMethodParameters(MethodParameters_attribute attr, P p);
         R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p);
         R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
         R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -479,6 +479,15 @@
             out.writeShort(entry.index);
         }
 
+        public Void visitMethodParameters(MethodParameters_attribute attr, ClassOutputStream out) {
+            out.writeByte(attr.method_parameter_table.length);
+            for (MethodParameters_attribute.Entry e : attr.method_parameter_table) {
+                out.writeShort(e.name_index);
+                out.writeInt(e.flags);
+            }
+            return null;
+        }
+
         public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, ClassOutputStream out) {
             annotationWriter.write(attr.annotations, out);
             return null;
--- a/langtools/src/share/classes/com/sun/tools/classfile/Dependencies.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Dependencies.java	Wed Jan 16 11:58:15 2013 -0800
@@ -142,6 +142,15 @@
     }
 
     /**
+     * Get a finder to do class dependency analysis.
+     *
+     * @return a Class dependency finder
+     */
+    public static Finder getClassDependencyFinder() {
+        return new ClassDependencyFinder();
+    }
+
+    /**
      * Get the finder used to locate the dependencies for a class.
      * @return the finder
      */
@@ -246,8 +255,6 @@
         return results;
     }
 
-
-
     /**
      * Find the dependencies of a class, using the current
      * {@link Dependencies#getFinder finder} and
@@ -306,38 +313,44 @@
      * A location identifying a class.
      */
     static class SimpleLocation implements Location {
-        public SimpleLocation(String className) {
-            this.className = className;
+        public SimpleLocation(String name) {
+            this.name = name;
+            this.className = name.replace('/', '.').replace('$', '.');
         }
 
-        /**
-         * Get the name of the class being depended on. This name will be used to
-         * locate the class file for transitive dependency analysis.
-         * @return the name of the class being depended on
-         */
+        public String getName() {
+            return name;
+        }
+
         public String getClassName() {
             return className;
         }
 
+        public String getPackageName() {
+            int i = name.lastIndexOf('/');
+            return (i > 0) ? name.substring(0, i).replace('/', '.') : "";
+        }
+
         @Override
         public boolean equals(Object other) {
             if (this == other)
                 return true;
             if (!(other instanceof SimpleLocation))
                 return false;
-            return (className.equals(((SimpleLocation) other).className));
+            return (name.equals(((SimpleLocation) other).name));
         }
 
         @Override
         public int hashCode() {
-            return className.hashCode();
+            return name.hashCode();
         }
 
         @Override
         public String toString() {
-            return className;
+            return name;
         }
 
+        private String name;
         private String className;
     }
 
@@ -431,9 +444,7 @@
         }
 
         public boolean accepts(Dependency dependency) {
-            String cn = dependency.getTarget().getClassName();
-            int lastSep = cn.lastIndexOf("/");
-            String pn = (lastSep == -1 ? "" : cn.substring(0, lastSep));
+            String pn = dependency.getTarget().getPackageName();
             if (packageNames.contains(pn))
                 return true;
 
@@ -451,8 +462,6 @@
         private final boolean matchSubpackages;
     }
 
-
-
     /**
      * This class identifies class names directly or indirectly in the constant pool.
      */
@@ -462,6 +471,26 @@
             for (CPInfo cpInfo: classfile.constant_pool.entries()) {
                 v.scan(cpInfo);
             }
+            try {
+                v.addClass(classfile.super_class);
+                v.addClasses(classfile.interfaces);
+                v.scan(classfile.attributes);
+
+                for (Field f : classfile.fields) {
+                    v.scan(f.descriptor, f.attributes);
+                }
+                for (Method m : classfile.methods) {
+                    v.scan(m.descriptor, m.attributes);
+                    Exceptions_attribute e =
+                        (Exceptions_attribute)m.attributes.get(Attribute.Exceptions);
+                    if (e != null) {
+                        v.addClasses(e.exception_index_table);
+                    }
+                }
+            } catch (ConstantPoolException e) {
+                throw new ClassFileError(e);
+            }
+
             return v.deps;
         }
     }
@@ -558,9 +587,7 @@
             void scan(Descriptor d, Attributes attrs) {
                 try {
                     scan(new Signature(d.index).getType(constant_pool));
-                    Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature);
-                    if (sa != null)
-                        scan(new Signature(sa.signature_index).getType(constant_pool));
+                    scan(attrs);
                 } catch (ConstantPoolException e) {
                     throw new ClassFileError(e);
                 }
@@ -574,6 +601,43 @@
                 t.accept(this, null);
             }
 
+            void scan(Attributes attrs) {
+                try {
+                    Signature_attribute sa = (Signature_attribute)attrs.get(Attribute.Signature);
+                    if (sa != null)
+                        scan(sa.getParsedSignature().getType(constant_pool));
+
+                    scan((RuntimeVisibleAnnotations_attribute)
+                            attrs.get(Attribute.RuntimeVisibleAnnotations));
+                    scan((RuntimeVisibleParameterAnnotations_attribute)
+                            attrs.get(Attribute.RuntimeVisibleParameterAnnotations));
+                } catch (ConstantPoolException e) {
+                    throw new ClassFileError(e);
+                }
+            }
+
+            private void scan(RuntimeAnnotations_attribute attr) throws ConstantPoolException {
+                if (attr == null) {
+                    return;
+                }
+                for (int i = 0; i < attr.annotations.length; i++) {
+                    int index = attr.annotations[i].type_index;
+                    scan(new Signature(index).getType(constant_pool));
+                }
+            }
+
+            private void scan(RuntimeParameterAnnotations_attribute attr) throws ConstantPoolException {
+                if (attr == null) {
+                    return;
+                }
+                for (int param = 0; param < attr.parameter_annotations.length; param++) {
+                    for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
+                        int index = attr.parameter_annotations[param][i].type_index;
+                        scan(new Signature(index).getType(constant_pool));
+                    }
+                }
+            }
+
             void addClass(int index) throws ConstantPoolException {
                 if (index != 0) {
                     String name = constant_pool.getClassInfo(index).getBaseName();
@@ -698,6 +762,7 @@
                 findDependencies(type.paramTypes);
                 findDependencies(type.returnType);
                 findDependencies(type.throwsTypes);
+                findDependencies(type.typeParamTypes);
                 return null;
             }
 
@@ -709,7 +774,7 @@
 
             public Void visitClassType(ClassType type, Void p) {
                 findDependencies(type.outerType);
-                addDependency(type.name);
+                addDependency(type.getBinaryName());
                 findDependencies(type.typeArgs);
                 return null;
             }
--- a/langtools/src/share/classes/com/sun/tools/classfile/Dependency.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Dependency.java	Wed Jan 16 11:58:15 2013 -0800
@@ -71,7 +71,19 @@
          * dependency analysis.
          * @return the name of the class containing the location.
          */
+        String getName();
+
+        /**
+         * Get the fully-qualified name of the class containing the location.
+         * @return the fully-qualified name of the class containing the location.
+         */
         String getClassName();
+
+        /**
+         * Get the package name of the class containing the location.
+         * @return the package name of the class containing the location.
+         */
+        String getPackageName();
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/classfile/MethodParameters_attribute.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See JVMS, section 4.8.13.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class MethodParameters_attribute extends Attribute {
+
+    public final int method_parameter_table_length;
+    public final Entry[] method_parameter_table;
+
+    MethodParameters_attribute(ClassReader cr,
+                              int name_index,
+                              int length)
+        throws IOException {
+        super(name_index, length);
+
+        method_parameter_table_length = cr.readUnsignedByte();
+        method_parameter_table = new Entry[method_parameter_table_length];
+        for (int i = 0; i < method_parameter_table_length; i++)
+            method_parameter_table[i] = new Entry(cr);
+    }
+
+    public MethodParameters_attribute(ConstantPool constant_pool,
+                                      Entry[] method_parameter_table)
+        throws ConstantPoolException {
+        this(constant_pool.getUTF8Index(Attribute.MethodParameters),
+             method_parameter_table);
+    }
+
+    public MethodParameters_attribute(int name_index,
+                                      Entry[] method_parameter_table) {
+        super(name_index, 1 + method_parameter_table.length * Entry.length());
+        this.method_parameter_table_length = method_parameter_table.length;
+        this.method_parameter_table = method_parameter_table;
+    }
+
+    public <R, D> R accept(Visitor<R, D> visitor, D data) {
+        return visitor.visitMethodParameters(this, data);
+    }
+
+    public static class Entry {
+        Entry(ClassReader cr) throws IOException {
+            name_index = cr.readUnsignedShort();
+            flags = cr.readInt();
+        }
+
+        public static int length() {
+            return 6;
+        }
+
+        public final int name_index;
+        public final int flags;
+    }
+
+}
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/AbstractMemberWriter.java	Wed Jan 16 11:58:15 2013 -0800
@@ -321,7 +321,8 @@
             code.addContent(" ");
         }
         if (member.isMethod()) {
-            if (((MethodDoc)member).isAbstract()) {
+            if (!(member.containingClass().isInterface()) &&
+                    ((MethodDoc)member).isAbstract()) {
                 code.addContent("abstract ");
             }
             // This check for isDefault() and the default modifier needs to be
@@ -329,7 +330,7 @@
             // method summary section. Once the default modifier is added
             // to the Modifier list on DocEnv and once it is updated to use the
             // javax.lang.model.element.Modifier, we will need to remove this.
-            else if (((MethodDoc)member).isDefault()) {
+            if (((MethodDoc)member).isDefault()) {
                 code.addContent("default ");
             }
         }
@@ -561,11 +562,14 @@
         if (member instanceof MethodDoc && !member.isAnnotationTypeElement()) {
             int methodType = (member.isStatic()) ? MethodTypes.STATIC.value() :
                     MethodTypes.INSTANCE.value();
-            methodType = (classdoc.isInterface() || ((MethodDoc)member).isAbstract()) ?
-                    methodType | MethodTypes.ABSTRACT.value() :
-                    methodType | MethodTypes.CONCRETE.value();
-            if (((MethodDoc)member).isDefault()) {
-                methodType = methodType | MethodTypes.DEFAULT.value();
+            if (member.containingClass().isInterface()) {
+                methodType = (((MethodDoc) member).isAbstract())
+                        ? methodType | MethodTypes.ABSTRACT.value()
+                        : methodType | MethodTypes.DEFAULT.value();
+            } else {
+                methodType = (((MethodDoc) member).isAbstract())
+                        ? methodType | MethodTypes.ABSTRACT.value()
+                        : methodType | MethodTypes.CONCRETE.value();
             }
             if (Util.isDeprecated(member) || Util.isDeprecated(classdoc)) {
                 methodType = methodType | MethodTypes.DEPRECATED.value();
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Wed Jan 16 11:58:15 2013 -0800
@@ -90,6 +90,16 @@
     protected boolean printedAnnotationHeading = false;
 
     /**
+     * To check whether the repeated annotations is documented or not.
+     */
+    private boolean isAnnotationDocumented = false;
+
+    /**
+     * To check whether the container annotations is documented or not.
+     */
+    private boolean isContainerDocumented = false;
+
+    /**
      * Constructor to construct the HtmlStandardWriter object.
      *
      * @param path File to be generated.
@@ -1793,50 +1803,66 @@
         StringBuilder annotation;
         for (int i = 0; i < descList.length; i++) {
             AnnotationTypeDoc annotationDoc = descList[i].annotationType();
-            if (! Util.isDocumentedAnnotation(annotationDoc)){
+            // If an annotation is not documented, do not add it to the list. If
+            // the annotation is of a repeatable type, and if it is not documented
+            // and also if its container annotation is not documented, do not add it
+            // to the list. If an annotation of a repeatable type is not documented
+            // but its container is documented, it will be added to the list.
+            if (! Util.isDocumentedAnnotation(annotationDoc) &&
+                    (!isAnnotationDocumented && !isContainerDocumented)) {
                 continue;
             }
             annotation = new StringBuilder();
+            isAnnotationDocumented = false;
             LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
                 LinkInfoImpl.CONTEXT_ANNOTATION, annotationDoc);
-            linkInfo.label = "@" + annotationDoc.name();
-            annotation.append(getLink(linkInfo));
             AnnotationDesc.ElementValuePair[] pairs = descList[i].elementValues();
-            if (pairs.length > 0) {
-                annotation.append('(');
+            // If the annotation is synthesized, do not print the container.
+            if (descList[i].isSynthesized()) {
                 for (int j = 0; j < pairs.length; j++) {
-                    if (j > 0) {
-                        annotation.append(",");
-                        if (linkBreak) {
-                            annotation.append(DocletConstants.NL);
-                            int spaces = annotationDoc.name().length() + 2;
-                            for (int k = 0; k < (spaces + indent); k++) {
-                                annotation.append(' ');
-                            }
-                        }
-                    }
-                    annotation.append(getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION,
-                        pairs[j].element(), pairs[j].element().name(), false));
-                    annotation.append('=');
                     AnnotationValue annotationValue = pairs[j].value();
                     List<AnnotationValue> annotationTypeValues = new ArrayList<AnnotationValue>();
                     if (annotationValue.value() instanceof AnnotationValue[]) {
                         AnnotationValue[] annotationArray =
-                            (AnnotationValue[]) annotationValue.value();
-                        for (int k = 0; k < annotationArray.length; k++) {
-                            annotationTypeValues.add(annotationArray[k]);
-                        }
+                                (AnnotationValue[]) annotationValue.value();
+                        annotationTypeValues.addAll(Arrays.asList(annotationArray));
                     } else {
                         annotationTypeValues.add(annotationValue);
                     }
-                    annotation.append(annotationTypeValues.size() == 1 ? "" : "{");
-                    for (Iterator<AnnotationValue> iter = annotationTypeValues.iterator(); iter.hasNext(); ) {
-                        annotation.append(annotationValueToString(iter.next()));
-                        annotation.append(iter.hasNext() ? "," : "");
+                    String sep = "";
+                    for (AnnotationValue av : annotationTypeValues) {
+                        annotation.append(sep);
+                        annotation.append(annotationValueToString(av));
+                        sep = " ";
                     }
-                    annotation.append(annotationTypeValues.size() == 1 ? "" : "}");
                 }
-                annotation.append(")");
+            }
+            else if (isAnnotationArray(pairs)) {
+                // If the container has 1 or more value defined and if the
+                // repeatable type annotation is not documented, do not print
+                // the container.
+                if (pairs.length == 1 && isAnnotationDocumented) {
+                    AnnotationValue[] annotationArray =
+                            (AnnotationValue[]) (pairs[0].value()).value();
+                    List<AnnotationValue> annotationTypeValues = new ArrayList<AnnotationValue>();
+                    annotationTypeValues.addAll(Arrays.asList(annotationArray));
+                    String sep = "";
+                    for (AnnotationValue av : annotationTypeValues) {
+                        annotation.append(sep);
+                        annotation.append(annotationValueToString(av));
+                        sep = " ";
+                    }
+                }
+                // If the container has 1 or more value defined and if the
+                // repeatable type annotation is not documented, print the container.
+                else {
+                    addAnnotations(annotationDoc, linkInfo, annotation, pairs,
+                        indent, false);
+                }
+            }
+            else {
+                addAnnotations(annotationDoc, linkInfo, annotation, pairs,
+                        indent, linkBreak);
             }
             annotation.append(linkBreak ? DocletConstants.NL : "");
             results.add(annotation.toString());
@@ -1844,6 +1870,91 @@
         return results;
     }
 
+    /**
+     * Add annotation to the annotation string.
+     *
+     * @param annotationDoc the annotation being documented
+     * @param linkInfo the information about the link
+     * @param annotation the annotation string to which the annotation will be added
+     * @param pairs annotation type element and value pairs
+     * @param indent the number of extra spaces to indent the annotations.
+     * @param linkBreak if true, add new line between each member value
+     */
+    private void addAnnotations(AnnotationTypeDoc annotationDoc, LinkInfoImpl linkInfo,
+            StringBuilder annotation, AnnotationDesc.ElementValuePair[] pairs,
+            int indent, boolean linkBreak) {
+        linkInfo.label = "@" + annotationDoc.name();
+        annotation.append(getLink(linkInfo));
+        if (pairs.length > 0) {
+            annotation.append('(');
+            for (int j = 0; j < pairs.length; j++) {
+                if (j > 0) {
+                    annotation.append(",");
+                    if (linkBreak) {
+                        annotation.append(DocletConstants.NL);
+                        int spaces = annotationDoc.name().length() + 2;
+                        for (int k = 0; k < (spaces + indent); k++) {
+                            annotation.append(' ');
+                        }
+                    }
+                }
+                annotation.append(getDocLink(LinkInfoImpl.CONTEXT_ANNOTATION,
+                        pairs[j].element(), pairs[j].element().name(), false));
+                annotation.append('=');
+                AnnotationValue annotationValue = pairs[j].value();
+                List<AnnotationValue> annotationTypeValues = new ArrayList<AnnotationValue>();
+                if (annotationValue.value() instanceof AnnotationValue[]) {
+                    AnnotationValue[] annotationArray =
+                            (AnnotationValue[]) annotationValue.value();
+                    annotationTypeValues.addAll(Arrays.asList(annotationArray));
+                } else {
+                    annotationTypeValues.add(annotationValue);
+                }
+                annotation.append(annotationTypeValues.size() == 1 ? "" : "{");
+                String sep = "";
+                for (AnnotationValue av : annotationTypeValues) {
+                    annotation.append(sep);
+                    annotation.append(annotationValueToString(av));
+                    sep = ",";
+                }
+                annotation.append(annotationTypeValues.size() == 1 ? "" : "}");
+                isContainerDocumented = false;
+            }
+            annotation.append(")");
+        }
+    }
+
+    /**
+     * Check if the annotation contains an array of annotation as a value. This
+     * check is to verify if a repeatable type annotation is present or not.
+     *
+     * @param pairs annotation type element and value pairs
+     *
+     * @return true if the annotation contains an array of annotation as a value.
+     */
+    private boolean isAnnotationArray(AnnotationDesc.ElementValuePair[] pairs) {
+        AnnotationValue annotationValue;
+        for (int j = 0; j < pairs.length; j++) {
+            annotationValue = pairs[j].value();
+            if (annotationValue.value() instanceof AnnotationValue[]) {
+                AnnotationValue[] annotationArray =
+                        (AnnotationValue[]) annotationValue.value();
+                if (annotationArray.length > 1) {
+                    if (annotationArray[0].value() instanceof AnnotationDesc) {
+                        AnnotationTypeDoc annotationDoc =
+                                ((AnnotationDesc) annotationArray[0].value()).annotationType();
+                        isContainerDocumented = true;
+                        if (Util.isDocumentedAnnotation(annotationDoc)) {
+                            isAnnotationDocumented = true;
+                        }
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
     private String annotationValueToString(AnnotationValue annotationValue) {
         if (annotationValue.value() instanceof Type) {
             Type type = (Type) annotationValue.value();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1283,8 +1283,9 @@
                 List<Name> paramNames = savedParameterNames;
                 savedParameterNames = null;
                 // discard the provided names if the list of names is the wrong size.
-                if (paramNames == null || paramNames.size() != type.getParameterTypes().size())
+                if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
                     paramNames = List.nil();
+                }
                 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
                 List<Name> remaining = paramNames;
                 // assert: remaining and paramNames are both empty or both
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Wed Jan 16 11:58:15 2013 -0800
@@ -38,6 +38,7 @@
 import javax.tools.JavaFileObject;
 
 import java.util.ArrayList;
+import java.util.EnumSet;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Queue;
@@ -177,29 +178,19 @@
          * attribution round must follow one or more speculative rounds.
          */
         Type check(ResultInfo resultInfo) {
+            return check(resultInfo, stuckVars(tree, env, resultInfo), basicCompleter);
+        }
+
+        Type check(ResultInfo resultInfo, List<Type> stuckVars, DeferredTypeCompleter deferredTypeCompleter) {
             DeferredAttrContext deferredAttrContext =
                     resultInfo.checkContext.deferredAttrContext();
             Assert.check(deferredAttrContext != emptyDeferredAttrContext);
-            List<Type> stuckVars = stuckVars(tree, env, resultInfo);
             if (stuckVars.nonEmpty()) {
                 deferredAttrContext.addDeferredAttrNode(this, resultInfo, stuckVars);
                 return Type.noType;
             } else {
                 try {
-                    switch (deferredAttrContext.mode) {
-                        case SPECULATIVE:
-                            Assert.check(mode == null ||
-                                    (mode == AttrMode.SPECULATIVE &&
-                                    speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).hasTag(NONE)));
-                            JCTree speculativeTree = attribSpeculative(tree, env, resultInfo);
-                            speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
-                            return speculativeTree.type;
-                        case CHECK:
-                            Assert.check(mode == AttrMode.SPECULATIVE);
-                            return attr.attribTree(tree, env, resultInfo);
-                    }
-                    Assert.error();
-                    return null;
+                    return deferredTypeCompleter.complete(this, resultInfo, deferredAttrContext);
                 } finally {
                     mode = deferredAttrContext.mode;
                 }
@@ -208,6 +199,43 @@
     }
 
     /**
+     * A completer for deferred types. Defines an entry point for type-checking
+     * a deferred type.
+     */
+    interface DeferredTypeCompleter {
+        /**
+         * Entry point for type-checking a deferred type. Depending on the
+         * circumstances, type-checking could amount to full attribution
+         * or partial structural check (aka potential applicability).
+         */
+        Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext);
+    }
+
+    /**
+     * A basic completer for deferred types. This completer type-checks a deferred type
+     * using attribution; depending on the attribution mode, this could be either standard
+     * or speculative attribution.
+     */
+    DeferredTypeCompleter basicCompleter = new DeferredTypeCompleter() {
+        public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
+            switch (deferredAttrContext.mode) {
+                case SPECULATIVE:
+                    Assert.check(dt.mode == null ||
+                            (dt.mode == AttrMode.SPECULATIVE &&
+                            dt.speculativeType(deferredAttrContext.msym, deferredAttrContext.phase).hasTag(NONE)));
+                    JCTree speculativeTree = attribSpeculative(dt.tree, dt.env, resultInfo);
+                    dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
+                    return speculativeTree.type;
+                case CHECK:
+                    Assert.check(dt.mode == AttrMode.SPECULATIVE);
+                    return attr.attribTree(dt.tree, dt.env, resultInfo);
+            }
+            Assert.error();
+            return null;
+        }
+    };
+
+    /**
      * The 'mode' in which the deferred type is to be type-checked
      */
     public enum AttrMode {
@@ -498,10 +526,80 @@
                 if (resultInfo.pt.hasTag(NONE) || resultInfo.pt.isErroneous()) {
             return List.nil();
         } else {
-            StuckChecker sc = new StuckChecker(resultInfo, env);
+            return stuckVarsInternal(tree, resultInfo.pt, resultInfo.checkContext.inferenceContext());
+        }
+    }
+    //where
+        private List<Type> stuckVarsInternal(JCTree tree, Type pt, Infer.InferenceContext inferenceContext) {
+            StuckChecker sc = new StuckChecker(pt, inferenceContext);
             sc.scan(tree);
             return List.from(sc.stuckVars);
         }
+
+    /**
+     * A special tree scanner that would only visit portions of a given tree.
+     * The set of nodes visited by the scanner can be customized at construction-time.
+     */
+    abstract static class FilterScanner extends TreeScanner {
+
+        final Filter<JCTree> treeFilter;
+
+        FilterScanner(final Set<JCTree.Tag> validTags) {
+            this.treeFilter = new Filter<JCTree>() {
+                public boolean accepts(JCTree t) {
+                    return validTags.contains(t.getTag());
+                }
+            };
+        }
+
+        @Override
+        public void scan(JCTree tree) {
+            if (tree != null) {
+                if (treeFilter.accepts(tree)) {
+                    super.scan(tree);
+                } else {
+                    skip(tree);
+                }
+            }
+        }
+
+        /**
+         * handler that is executed when a node has been discarded
+         */
+        abstract void skip(JCTree tree);
+    }
+
+    /**
+     * A tree scanner suitable for visiting the target-type dependent nodes of
+     * a given argument expression.
+     */
+    static class PolyScanner extends FilterScanner {
+
+        PolyScanner() {
+            super(EnumSet.of(CONDEXPR, PARENS, LAMBDA, REFERENCE));
+        }
+
+        @Override
+        void skip(JCTree tree) {
+            //do nothing
+        }
+    }
+
+    /**
+     * A tree scanner suitable for visiting the target-type dependent nodes nested
+     * within a lambda expression body.
+     */
+    static class LambdaReturnScanner extends FilterScanner {
+
+        LambdaReturnScanner() {
+            super(EnumSet.of(BLOCK, CASE, CATCH, DOLOOP, FOREACHLOOP,
+                    FORLOOP, RETURN, SYNCHRONIZED, SWITCH, TRY, WHILELOOP));
+        }
+
+        @Override
+        void skip(JCTree tree) {
+            //do nothing
+        }
     }
 
     /**
@@ -510,83 +608,32 @@
      * inferring types that make some of the nested expressions incompatible
      * with their corresponding instantiated target
      */
-    class StuckChecker extends TreeScanner {
+    class StuckChecker extends PolyScanner {
 
         Type pt;
-        Filter<JCTree> treeFilter;
         Infer.InferenceContext inferenceContext;
         Set<Type> stuckVars = new LinkedHashSet<Type>();
-        Env<AttrContext> env;
 
-        final Filter<JCTree> argsFilter = new Filter<JCTree>() {
-            public boolean accepts(JCTree t) {
-                switch (t.getTag()) {
-                    case CONDEXPR:
-                    case LAMBDA:
-                    case PARENS:
-                    case REFERENCE:
-                        return true;
-                    default:
-                        return false;
-                }
-            }
-        };
-
-        final Filter<JCTree> lambdaBodyFilter = new Filter<JCTree>() {
-            public boolean accepts(JCTree t) {
-                switch (t.getTag()) {
-                    case BLOCK: case CASE: case CATCH: case DOLOOP:
-                    case FOREACHLOOP: case FORLOOP: case RETURN:
-                    case SYNCHRONIZED: case SWITCH: case TRY: case WHILELOOP:
-                        return true;
-                    default:
-                        return false;
-                }
-            }
-        };
-
-        StuckChecker(ResultInfo resultInfo, Env<AttrContext> env) {
-            this.pt = resultInfo.pt;
-            this.inferenceContext = resultInfo.checkContext.inferenceContext();
-            this.treeFilter = argsFilter;
-            this.env = env;
-        }
-
-        @Override
-        public void scan(JCTree tree) {
-            if (tree != null && treeFilter.accepts(tree)) {
-                super.scan(tree);
-            }
+        StuckChecker(Type pt, Infer.InferenceContext inferenceContext) {
+            this.pt = pt;
+            this.inferenceContext = inferenceContext;
         }
 
         @Override
         public void visitLambda(JCLambda tree) {
-            Type prevPt = pt;
-            Filter<JCTree> prevFilter = treeFilter;
-            try {
-                if (inferenceContext.inferenceVars().contains(pt)) {
-                    stuckVars.add(pt);
-                }
-                if (!types.isFunctionalInterface(pt.tsym)) {
-                    return;
-                }
-                Type descType = types.findDescriptorType(pt);
-                List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
-                if (!TreeInfo.isExplicitLambda(tree) &&
-                        freeArgVars.nonEmpty()) {
-                    stuckVars.addAll(freeArgVars);
-                }
-                pt = descType.getReturnType();
-                if (tree.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
-                    scan(tree.getBody());
-                } else {
-                    treeFilter = lambdaBodyFilter;
-                    super.visitLambda(tree);
-                }
-            } finally {
-                pt = prevPt;
-                treeFilter = prevFilter;
+            if (inferenceContext.inferenceVars().contains(pt)) {
+                stuckVars.add(pt);
+            }
+            if (!types.isFunctionalInterface(pt.tsym)) {
+                return;
             }
+            Type descType = types.findDescriptorType(pt);
+            List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
+            if (!TreeInfo.isExplicitLambda(tree) &&
+                    freeArgVars.nonEmpty()) {
+                stuckVars.addAll(freeArgVars);
+            }
+            scanLambdaBody(tree, descType.getReturnType());
         }
 
         @Override
@@ -605,16 +652,19 @@
             stuckVars.addAll(freeArgVars);
         }
 
-        @Override
-        public void visitReturn(JCReturn tree) {
-            Filter<JCTree> prevFilter = treeFilter;
-            try {
-                treeFilter = argsFilter;
-                if (tree.expr != null) {
-                    scan(tree.expr);
-                }
-            } finally {
-                treeFilter = prevFilter;
+        void scanLambdaBody(JCLambda lambda, final Type pt) {
+            if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
+                stuckVars.addAll(stuckVarsInternal(lambda.body, pt, inferenceContext));
+            } else {
+                LambdaReturnScanner lambdaScanner = new LambdaReturnScanner() {
+                    @Override
+                    public void visitReturn(JCReturn tree) {
+                        if (tree.expr != null) {
+                            stuckVars.addAll(stuckVarsInternal(tree.expr, pt, inferenceContext));
+                        }
+                    }
+                };
+                lambdaScanner.scan(lambda.body);
             }
         }
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Jan 16 11:58:15 2013 -0800
@@ -114,7 +114,7 @@
         }
     }
 
-    private final InferenceException inferenceException;
+    final InferenceException inferenceException;
 
 /***************************************************************************
  * Mini/Maximization of UndetVars
@@ -271,15 +271,19 @@
                                   boolean allowBoxing,
                                   boolean useVarargs,
                                   Resolve.MethodResolutionContext resolveContext,
+                                  Resolve.MethodCheck methodCheck,
                                   Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
         final InferenceContext inferenceContext = new InferenceContext(tvars, this, true);
         inferenceException.clear();
 
+        DeferredAttr.DeferredAttrContext deferredAttrContext =
+                resolveContext.deferredAttrContext(msym, inferenceContext);
+
         try {
-            rs.checkRawArgumentsAcceptable(env, msym, resolveContext.attrMode(), inferenceContext,
-                    argtypes, mt.getParameterTypes(), allowBoxing, useVarargs, warn,
-                    new InferenceCheckHandler(inferenceContext));
+            methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn);
+
+            deferredAttrContext.complete();
 
             // minimize as yet undetermined type variables
             for (Type t : inferenceContext.undetvars) {
@@ -309,32 +313,6 @@
             inferenceContext.notifyChange(types);
         }
     }
-    //where
-
-        /** inference check handler **/
-        class InferenceCheckHandler implements Resolve.MethodCheckHandler {
-
-            InferenceContext inferenceContext;
-
-            public InferenceCheckHandler(InferenceContext inferenceContext) {
-                this.inferenceContext = inferenceContext;
-            }
-
-            public InapplicableMethodException arityMismatch() {
-                return inferenceException.setMessage("infer.arg.length.mismatch", inferenceContext.inferenceVars());
-            }
-            public InapplicableMethodException argumentMismatch(boolean varargs, JCDiagnostic details) {
-                String key = varargs ?
-                        "infer.varargs.argument.mismatch" :
-                        "infer.no.conforming.assignment.exists";
-                return inferenceException.setMessage(key,
-                        inferenceContext.inferenceVars(), details);
-            }
-            public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) {
-                return inferenceException.setMessage("inaccessible.varargs.type",
-                        expected, Kinds.kindName(location), location);
-            }
-        }
 
     /** check that type parameters are within their bounds.
      */
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Wed Jan 16 11:58:15 2013 -0800
@@ -506,6 +506,7 @@
                         List<Type> typeargtypes,
                         boolean allowBoxing,
                         boolean useVarargs,
+                        MethodCheck methodCheck,
                         Warner warn) throws Infer.InferenceException {
 
         Type mt = types.memberType(site, m);
@@ -558,10 +559,11 @@
                                     allowBoxing,
                                     useVarargs,
                                     currentResolutionContext,
+                                    methodCheck,
                                     warn);
 
-        checkRawArgumentsAcceptable(env, m, argtypes, mt.getParameterTypes(),
-                                allowBoxing, useVarargs, warn);
+        methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext),
+                                argtypes, mt.getParameterTypes(), warn);
         return mt;
     }
 
@@ -578,7 +580,7 @@
             currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK;
             MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
-                    step.isBoxingRequired(), step.isVarargsRequired(), warn);
+                    step.isBoxingRequired(), step.isVarargsRequired(), resolveMethodCheck, warn);
         }
         finally {
             currentResolutionContext = prevContext;
@@ -595,80 +597,65 @@
                      List<Type> typeargtypes,
                      boolean allowBoxing,
                      boolean useVarargs,
+                     MethodCheck methodCheck,
                      Warner warn) {
         try {
             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
-                                  allowBoxing, useVarargs, warn);
+                                  allowBoxing, useVarargs, methodCheck, warn);
         } catch (InapplicableMethodException ex) {
             return null;
         }
     }
 
-    /** Check if a parameter list accepts a list of args.
+    /**
+     * This interface defines an entry point that should be used to perform a
+     * method check. A method check usually consist in determining as to whether
+     * a set of types (actuals) is compatible with another set of types (formals).
+     * Since the notion of compatibility can vary depending on the circumstances,
+     * this interfaces allows to easily add new pluggable method check routines.
      */
-    boolean argumentsAcceptable(Env<AttrContext> env,
-                                Symbol msym,
+    interface MethodCheck {
+        /**
+         * Main method check routine. A method check usually consist in determining
+         * as to whether a set of types (actuals) is compatible with another set of
+         * types (formals). If an incompatibility is found, an unchecked exception
+         * is assumed to be thrown.
+         */
+        void argumentsAcceptable(Env<AttrContext> env,
+                                DeferredAttrContext deferredAttrContext,
                                 List<Type> argtypes,
                                 List<Type> formals,
-                                boolean allowBoxing,
-                                boolean useVarargs,
-                                Warner warn) {
-        try {
-            checkRawArgumentsAcceptable(env, msym, argtypes, formals, allowBoxing, useVarargs, warn);
-            return true;
-        } catch (InapplicableMethodException ex) {
-            return false;
-        }
-    }
-    /**
-     * A check handler is used by the main method applicability routine in order
-     * to handle specific method applicability failures. It is assumed that a class
-     * implementing this interface should throw exceptions that are a subtype of
-     * InapplicableMethodException (see below). Such exception will terminate the
-     * method applicability check and propagate important info outwards (for the
-     * purpose of generating better diagnostics).
-     */
-    interface MethodCheckHandler {
-        /* The number of actuals and formals differ */
-        InapplicableMethodException arityMismatch();
-        /* An actual argument type does not conform to the corresponding formal type */
-        InapplicableMethodException argumentMismatch(boolean varargs, JCDiagnostic details);
-        /* The element type of a varargs is not accessible in the current context */
-        InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected);
+                                Warner warn);
     }
 
     /**
-     * Basic method check handler used within Resolve - all methods end up
-     * throwing InapplicableMethodException; a diagnostic fragment that describes
-     * the cause as to why the method is not applicable is set on the exception
-     * before it is thrown.
+     * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
      */
-    MethodCheckHandler resolveHandler = new MethodCheckHandler() {
-            public InapplicableMethodException arityMismatch() {
-                return inapplicableMethodException.setMessage("arg.length.mismatch");
-            }
-            public InapplicableMethodException argumentMismatch(boolean varargs, JCDiagnostic details) {
-                String key = varargs ?
-                        "varargs.argument.mismatch" :
-                        "no.conforming.assignment.exists";
-                return inapplicableMethodException.setMessage(key,
-                        details);
-            }
-            public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) {
-                return inapplicableMethodException.setMessage("inaccessible.varargs.type",
-                        expected, Kinds.kindName(location), location);
-            }
-    };
-
-    void checkRawArgumentsAcceptable(Env<AttrContext> env,
-                                Symbol msym,
-                                List<Type> argtypes,
-                                List<Type> formals,
-                                boolean allowBoxing,
-                                boolean useVarargs,
-                                Warner warn) {
-        checkRawArgumentsAcceptable(env, msym, currentResolutionContext.attrMode(), infer.emptyContext, argtypes, formals,
-                allowBoxing, useVarargs, warn, resolveHandler);
+    enum MethodCheckDiag {
+        /**
+         * Actuals and formals differs in length.
+         */
+        ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
+        /**
+         * An actual is incompatible with a formal.
+         */
+        ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
+        /**
+         * An actual is incompatible with the varargs element type.
+         */
+        VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
+        /**
+         * The varargs element type is inaccessible.
+         */
+        INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
+
+        final String basicKey;
+        final String inferKey;
+
+        MethodCheckDiag(String basicKey, String inferKey) {
+            this.basicKey = basicKey;
+            this.inferKey = inferKey;
+        }
     }
 
     /**
@@ -689,68 +676,94 @@
      *
      * A method check handler (see above) is used in order to report errors.
      */
-    void checkRawArgumentsAcceptable(final Env<AttrContext> env,
-                                Symbol msym,
-                                DeferredAttr.AttrMode mode,
-                                final Infer.InferenceContext inferenceContext,
-                                List<Type> argtypes,
-                                List<Type> formals,
-                                boolean allowBoxing,
-                                boolean useVarargs,
-                                Warner warn,
-                                final MethodCheckHandler handler) {
-        Type varargsFormal = useVarargs ? formals.last() : null;
-
-        if (varargsFormal == null &&
-                argtypes.size() != formals.size()) {
-            throw handler.arityMismatch(); // not enough args
-        }
-
-        DeferredAttr.DeferredAttrContext deferredAttrContext =
-                deferredAttr.new DeferredAttrContext(mode, msym, currentResolutionContext.step, inferenceContext);
-
-        while (argtypes.nonEmpty() && formals.head != varargsFormal) {
-            ResultInfo mresult = methodCheckResult(formals.head, allowBoxing, false, inferenceContext, deferredAttrContext, handler, warn);
-            mresult.check(null, argtypes.head);
-            argtypes = argtypes.tail;
-            formals = formals.tail;
-        }
-
-        if (formals.head != varargsFormal) {
-            throw handler.arityMismatch(); // not enough args
-        }
-
-        if (useVarargs) {
-            //note: if applicability check is triggered by most specific test,
-            //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
-            final Type elt = types.elemtype(varargsFormal);
-            ResultInfo mresult = methodCheckResult(elt, allowBoxing, true, inferenceContext, deferredAttrContext, handler, warn);
-            while (argtypes.nonEmpty()) {
+    MethodCheck resolveMethodCheck = new MethodCheck() {
+        @Override
+        public void argumentsAcceptable(final Env<AttrContext> env,
+                                    DeferredAttrContext deferredAttrContext,
+                                    List<Type> argtypes,
+                                    List<Type> formals,
+                                    Warner warn) {
+            //should we expand formals?
+            boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
+
+            //inference context used during this method check
+            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
+
+            Type varargsFormal = useVarargs ? formals.last() : null;
+
+            if (varargsFormal == null &&
+                    argtypes.size() != formals.size()) {
+                report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+            }
+
+            while (argtypes.nonEmpty() && formals.head != varargsFormal) {
+                ResultInfo mresult = methodCheckResult(false, formals.head, deferredAttrContext, warn);
                 mresult.check(null, argtypes.head);
                 argtypes = argtypes.tail;
+                formals = formals.tail;
             }
-            //check varargs element type accessibility
-            varargsAccessible(env, elt, handler, inferenceContext);
-        }
-
-        deferredAttrContext.complete();
-    }
-
-    void varargsAccessible(final Env<AttrContext> env, final Type t, final Resolve.MethodCheckHandler handler, final InferenceContext inferenceContext) {
-        if (inferenceContext.free(t)) {
-            inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
-                @Override
-                public void typesInferred(InferenceContext inferenceContext) {
-                    varargsAccessible(env, inferenceContext.asInstType(t, types), handler, inferenceContext);
+
+            if (formals.head != varargsFormal) {
+                report(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
+            }
+
+            if (useVarargs) {
+                //note: if applicability check is triggered by most specific test,
+                //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
+                final Type elt = types.elemtype(varargsFormal);
+                ResultInfo mresult = methodCheckResult(true, elt, deferredAttrContext, warn);
+                while (argtypes.nonEmpty()) {
+                    mresult.check(null, argtypes.head);
+                    argtypes = argtypes.tail;
                 }
-            });
-        } else {
-            if (!isAccessible(env, t)) {
-                Symbol location = env.enclClass.sym;
-                throw handler.inaccessibleVarargs(location, t);
+                //check varargs element type accessibility
+                varargsAccessible(env, elt, inferenceContext);
             }
         }
-    }
+
+        private void report(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
+            boolean inferDiag = inferenceContext != infer.emptyContext;
+            InapplicableMethodException ex = inferDiag ?
+                    infer.inferenceException : inapplicableMethodException;
+            if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
+                Object[] args2 = new Object[args.length + 1];
+                System.arraycopy(args, 0, args2, 1, args.length);
+                args2[0] = inferenceContext.inferenceVars();
+                args = args2;
+            }
+            throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args);
+        }
+
+        private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
+            if (inferenceContext.free(t)) {
+                inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
+                    @Override
+                    public void typesInferred(InferenceContext inferenceContext) {
+                        varargsAccessible(env, inferenceContext.asInstType(t, types), inferenceContext);
+                    }
+                });
+            } else {
+                if (!isAccessible(env, t)) {
+                    Symbol location = env.enclClass.sym;
+                    report(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
+                }
+            }
+        }
+
+        private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
+                final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
+            CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
+                MethodCheckDiag methodDiag = varargsCheck ?
+                                 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
+
+                @Override
+                public void report(DiagnosticPosition pos, JCDiagnostic details) {
+                    report(methodDiag, deferredAttrContext.inferenceContext, details);
+                }
+            };
+            return new MethodResultInfo(to, checkContext);
+        }
+    };
 
     /**
      * Check context to be used during method applicability checks. A method check
@@ -758,23 +771,24 @@
      */
     abstract class MethodCheckContext implements CheckContext {
 
-        MethodCheckHandler handler;
-        boolean useVarargs;
-        Infer.InferenceContext inferenceContext;
+        boolean strict;
         DeferredAttrContext deferredAttrContext;
         Warner rsWarner;
 
-        public MethodCheckContext(MethodCheckHandler handler, boolean useVarargs,
-                Infer.InferenceContext inferenceContext, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
-            this.handler = handler;
-            this.useVarargs = useVarargs;
-            this.inferenceContext = inferenceContext;
-            this.deferredAttrContext = deferredAttrContext;
-            this.rsWarner = rsWarner;
+        public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
+           this.strict = strict;
+           this.deferredAttrContext = deferredAttrContext;
+           this.rsWarner = rsWarner;
+        }
+
+        public boolean compatible(Type found, Type req, Warner warn) {
+            return strict ?
+                    types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req, types), warn) :
+                    types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req, types), warn);
         }
 
         public void report(DiagnosticPosition pos, JCDiagnostic details) {
-            throw handler.argumentMismatch(useVarargs, details);
+            throw inapplicableMethodException.setMessage(details);
         }
 
         public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
@@ -782,7 +796,7 @@
         }
 
         public InferenceContext inferenceContext() {
-            return inferenceContext;
+            return deferredAttrContext.inferenceContext;
         }
 
         public DeferredAttrContext deferredAttrContext() {
@@ -791,56 +805,13 @@
     }
 
     /**
-     * Subclass of method check context class that implements strict method conversion.
-     * Strict method conversion checks compatibility between types using subtyping tests.
-     */
-    class StrictMethodContext extends MethodCheckContext {
-
-        public StrictMethodContext(MethodCheckHandler handler, boolean useVarargs,
-                Infer.InferenceContext inferenceContext, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
-            super(handler, useVarargs, inferenceContext, deferredAttrContext, rsWarner);
-        }
-
-        public boolean compatible(Type found, Type req, Warner warn) {
-            return types.isSubtypeUnchecked(found, inferenceContext.asFree(req, types), warn);
-        }
-    }
-
-    /**
-     * Subclass of method check context class that implements loose method conversion.
-     * Loose method conversion checks compatibility between types using method conversion tests.
+     * ResultInfo class to be used during method applicability checks. Check
+     * for deferred types goes through special path.
      */
-    class LooseMethodContext extends MethodCheckContext {
-
-        public LooseMethodContext(MethodCheckHandler handler, boolean useVarargs,
-                Infer.InferenceContext inferenceContext, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
-            super(handler, useVarargs, inferenceContext, deferredAttrContext, rsWarner);
-        }
-
-        public boolean compatible(Type found, Type req, Warner warn) {
-            return types.isConvertible(found, inferenceContext.asFree(req, types), warn);
-        }
-    }
-
-    /**
-     * Create a method check context to be used during method applicability check
-     */
-    ResultInfo methodCheckResult(Type to, boolean allowBoxing, boolean useVarargs,
-            Infer.InferenceContext inferenceContext, DeferredAttr.DeferredAttrContext deferredAttrContext,
-            MethodCheckHandler methodHandler, Warner rsWarner) {
-        MethodCheckContext checkContext = allowBoxing ?
-                new LooseMethodContext(methodHandler, useVarargs, inferenceContext, deferredAttrContext, rsWarner) :
-                new StrictMethodContext(methodHandler, useVarargs, inferenceContext, deferredAttrContext, rsWarner);
-        return new MethodResultInfo(to, checkContext, deferredAttrContext);
-    }
-
     class MethodResultInfo extends ResultInfo {
 
-        DeferredAttr.DeferredAttrContext deferredAttrContext;
-
-        public MethodResultInfo(Type pt, CheckContext checkContext, DeferredAttr.DeferredAttrContext deferredAttrContext) {
+        public MethodResultInfo(Type pt, CheckContext checkContext) {
             attr.super(VAL, pt, checkContext);
-            this.deferredAttrContext = deferredAttrContext;
         }
 
         @Override
@@ -855,12 +826,12 @@
 
         @Override
         protected MethodResultInfo dup(Type newPt) {
-            return new MethodResultInfo(newPt, checkContext, deferredAttrContext);
+            return new MethodResultInfo(newPt, checkContext);
         }
 
         @Override
         protected ResultInfo dup(CheckContext newContext) {
-            return new MethodResultInfo(pt, newContext, deferredAttrContext);
+            return new MethodResultInfo(pt, newContext);
         }
     }
 
@@ -1071,7 +1042,7 @@
         Assert.check(sym.kind < AMBIGUOUS);
         try {
             Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
-                               allowBoxing, useVarargs, types.noWarnings);
+                               allowBoxing, useVarargs, resolveMethodCheck, types.noWarnings);
             if (!operator)
                 currentResolutionContext.addApplicableCandidate(sym, mt);
         } catch (InapplicableMethodException ex) {
@@ -1151,52 +1122,20 @@
                 if (m1Abstract && !m2Abstract) return m2;
                 if (m2Abstract && !m1Abstract) return m1;
                 // both abstract or both concrete
-                if (!m1Abstract && !m2Abstract)
-                    return ambiguityError(m1, m2);
-                // check that both signatures have the same erasure
-                if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
-                                       m2.erasure(types).getParameterTypes()))
-                    return ambiguityError(m1, m2);
-                // both abstract, neither overridden; merge throws clause and result type
-                Type mst = mostSpecificReturnType(mt1, mt2);
-                if (mst == null) {
-                    // Theoretically, this can't happen, but it is possible
-                    // due to error recovery or mixing incompatible class files
-                    return ambiguityError(m1, m2);
-                }
-                Symbol mostSpecific = mst == mt1 ? m1 : m2;
-                List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
-                Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
-                MethodSymbol result = new MethodSymbol(
-                        mostSpecific.flags(),
-                        mostSpecific.name,
-                        newSig,
-                        mostSpecific.owner) {
-                    @Override
-                    public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
-                        if (origin == site.tsym)
-                            return this;
-                        else
-                            return super.implementation(origin, types, checkResult);
-                        }
-                    };
-                return result;
+                return ambiguityError(m1, m2);
             }
             if (m1SignatureMoreSpecific) return m1;
             if (m2SignatureMoreSpecific) return m2;
             return ambiguityError(m1, m2);
         case AMBIGUOUS:
+            //check if m1 is more specific than all ambiguous methods in m2
             AmbiguityError e = (AmbiguityError)m2;
-            Symbol err1 = mostSpecific(argtypes, m1, e.sym, env, site, allowBoxing, useVarargs);
-            Symbol err2 = mostSpecific(argtypes, m1, e.sym2, env, site, allowBoxing, useVarargs);
-            if (err1 == err2) return err1;
-            if (err1 == e.sym && err2 == e.sym2) return m2;
-            if (err1 instanceof AmbiguityError &&
-                err2 instanceof AmbiguityError &&
-                ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
-                return ambiguityError(m1, m2);
-            else
-                return ambiguityError(err1, err2);
+            for (Symbol s : e.ambiguousSyms) {
+                if (mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs) != m1) {
+                    return e.addAmbiguousSymbol(m1);
+                }
+            }
+            return m1;
         default:
             throw new AssertionError();
         }
@@ -1274,12 +1213,19 @@
     }
     //where
     private boolean invocationMoreSpecific(Env<AttrContext> env, Type site, Symbol m2, List<Type> argtypes1, boolean allowBoxing, boolean useVarargs) {
-        noteWarner.clear();
-        Type mst = instantiate(env, site, m2, null,
-                types.lowerBounds(argtypes1), null,
-                allowBoxing, false, noteWarner);
-        return mst != null &&
-                !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
+        MethodResolutionContext prevContext = currentResolutionContext;
+        try {
+            currentResolutionContext = new MethodResolutionContext();
+            currentResolutionContext.step = allowBoxing ? BOX : BASIC;
+            noteWarner.clear();
+            Type mst = instantiate(env, site, m2, null,
+                    types.lowerBounds(argtypes1), null,
+                    allowBoxing, false, resolveMethodCheck, noteWarner);
+            return mst != null &&
+                    !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
+        } finally {
+            currentResolutionContext = prevContext;
+        }
     }
     //where
     private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
@@ -2366,9 +2312,11 @@
         try {
             currentResolutionContext = new MethodResolutionContext();
             Name name = treeinfo.operatorName(optag);
+            env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC;
             Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
                                     null, false, false, true);
             if (boxingEnabled && sym.kind >= WRONG_MTHS)
+                env.info.pendingResolutionPhase = currentResolutionContext.step = BOX;
                 sym = findMethod(env, syms.predefClass.type, name, argtypes,
                                  null, true, false, true);
             return accessMethod(sym, pos, env.enclClass.sym.type, name,
@@ -2524,6 +2472,10 @@
 
         @Override
         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+            if (sym.kind == AMBIGUOUS) {
+                AmbiguityError a_err = (AmbiguityError)sym;
+                sym = a_err.mergeAbstracts(site);
+            }
             if (sym.kind >= AMBIGUOUS) {
                 //if nothing is found return the 'first' error
                 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
@@ -2579,6 +2531,10 @@
         abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
 
         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+            if (sym.kind == AMBIGUOUS) {
+                AmbiguityError a_err = (AmbiguityError)sym;
+                sym = a_err.mergeAbstracts(site);
+            }
             //skip error reporting
             return sym;
         }
@@ -3014,9 +2970,7 @@
 
         @Override
         public Symbol access(Name name, TypeSymbol location) {
-            if (sym.kind >= AMBIGUOUS)
-                return ((ResolveError)sym).access(name, location);
-            else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
+            if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
                 return types.createErrorType(name, location, sym.type).tsym;
             else
                 return sym;
@@ -3338,14 +3292,32 @@
      * (either methods, constructors or operands) are ambiguous
      * given an actual arguments/type argument list.
      */
-    class AmbiguityError extends InvalidSymbolError {
+    class AmbiguityError extends ResolveError {
 
         /** The other maximally specific symbol */
-        Symbol sym2;
+        List<Symbol> ambiguousSyms = List.nil();
+
+        @Override
+        public boolean exists() {
+            return true;
+        }
 
         AmbiguityError(Symbol sym1, Symbol sym2) {
-            super(AMBIGUOUS, sym1, "ambiguity error");
-            this.sym2 = sym2;
+            super(AMBIGUOUS, "ambiguity error");
+            ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
+        }
+
+        private List<Symbol> flatten(Symbol sym) {
+            if (sym.kind == AMBIGUOUS) {
+                return ((AmbiguityError)sym).ambiguousSyms;
+            } else {
+                return List.of(sym);
+            }
+        }
+
+        AmbiguityError addAmbiguousSymbol(Symbol s) {
+            ambiguousSyms = ambiguousSyms.prepend(s);
+            return this;
         }
 
         @Override
@@ -3356,24 +3328,60 @@
                 Name name,
                 List<Type> argtypes,
                 List<Type> typeargtypes) {
-            AmbiguityError pair = this;
-            while (true) {
-                if (pair.sym.kind == AMBIGUOUS)
-                    pair = (AmbiguityError)pair.sym;
-                else if (pair.sym2.kind == AMBIGUOUS)
-                    pair = (AmbiguityError)pair.sym2;
-                else break;
-            }
-            Name sname = pair.sym.name;
-            if (sname == names.init) sname = pair.sym.owner.name;
+            List<Symbol> diagSyms = ambiguousSyms.reverse();
+            Symbol s1 = diagSyms.head;
+            Symbol s2 = diagSyms.tail.head;
+            Name sname = s1.name;
+            if (sname == names.init) sname = s1.owner.name;
             return diags.create(dkind, log.currentSource(),
                       pos, "ref.ambiguous", sname,
-                      kindName(pair.sym),
-                      pair.sym,
-                      pair.sym.location(site, types),
-                      kindName(pair.sym2),
-                      pair.sym2,
-                      pair.sym2.location(site, types));
+                      kindName(s1),
+                      s1,
+                      s1.location(site, types),
+                      kindName(s2),
+                      s2,
+                      s2.location(site, types));
+        }
+
+        /**
+         * If multiple applicable methods are found during overload and none of them
+         * is more specific than the others, attempt to merge their signatures.
+         */
+        Symbol mergeAbstracts(Type site) {
+            Symbol fst = ambiguousSyms.last();
+            Symbol res = fst;
+            for (Symbol s : ambiguousSyms.reverse()) {
+                Type mt1 = types.memberType(site, res);
+                Type mt2 = types.memberType(site, s);
+                if ((s.flags() & ABSTRACT) == 0 ||
+                        !types.overrideEquivalent(mt1, mt2) ||
+                        !types.isSameTypes(fst.erasure(types).getParameterTypes(),
+                                       s.erasure(types).getParameterTypes())) {
+                    //ambiguity cannot be resolved
+                    return this;
+                } else {
+                    Type mst = mostSpecificReturnType(mt1, mt2);
+                    if (mst == null) {
+                        // Theoretically, this can't happen, but it is possible
+                        // due to error recovery or mixing incompatible class files
+                        return this;
+                    }
+                    Symbol mostSpecific = mst == mt1 ? res : s;
+                    List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
+                    Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
+                    res = new MethodSymbol(
+                            mostSpecific.flags(),
+                            mostSpecific.name,
+                            newSig,
+                            mostSpecific.owner);
+                }
+            }
+            return res;
+        }
+
+        @Override
+        protected Symbol access(Name name, TypeSymbol location) {
+            return ambiguousSyms.last();
         }
     }
 
@@ -3450,6 +3458,10 @@
             candidates = candidates.append(c);
         }
 
+        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext) {
+            return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext);
+        }
+
         /**
          * This class represents an overload resolution candidate. There are two
          * kinds of candidates: applicable methods and inapplicable methods;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Jan 16 11:58:15 2013 -0800
@@ -217,6 +217,13 @@
      */
     boolean haveParameterNameIndices;
 
+    /** Set this to false every time we start reading a method
+     * and are saving parameter names.  Set it to true when we see
+     * MethodParameters, if it's set when we see a LocalVariableTable,
+     * then we ignore the parameter names from the LVT.
+     */
+    boolean sawMethodParameters;
+
     /**
      * The set of attribute names for which warnings have been generated for the current class
      */
@@ -984,7 +991,7 @@
             new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
                 protected void read(Symbol sym, int attrLen) {
                     int newbp = bp + attrLen;
-                    if (saveParameterNames) {
+                    if (saveParameterNames && !sawMethodParameters) {
                         // Pick up parameter names from the variable table.
                         // Parameter names are not explicitly identified as such,
                         // but all parameter name entries in the LocalVariableTable
@@ -1017,6 +1024,25 @@
                 }
             },
 
+            new AttributeReader(names.MethodParameters, V52, MEMBER_ATTRIBUTE) {
+                protected void read(Symbol sym, int attrlen) {
+                    int newbp = bp + attrlen;
+                    if (saveParameterNames) {
+                        sawMethodParameters = true;
+                        int numEntries = nextByte();
+                        parameterNameIndices = new int[numEntries];
+                        haveParameterNameIndices = true;
+                        for (int i = 0; i < numEntries; i++) {
+                            int nameIndex = nextChar();
+                            int flags = nextInt();
+                            parameterNameIndices[i] = nameIndex;
+                        }
+                    }
+                    bp = newbp;
+                }
+            },
+
+
             new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
                 protected void read(Symbol sym, int attrLen) {
                     ClassSymbol c = (ClassSymbol) sym;
@@ -1826,6 +1852,7 @@
         } else
             Arrays.fill(parameterNameIndices, 0);
         haveParameterNameIndices = false;
+        sawMethodParameters = false;
     }
 
     /**
@@ -1845,12 +1872,16 @@
         // if no names were found in the class file, there's nothing more to do
         if (!haveParameterNameIndices)
             return;
-
-        int firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
-        // the code in readMethod may have skipped the first parameter when
-        // setting up the MethodType. If so, we make a corresponding allowance
-        // here for the position of the first parameter.  Note that this
-        // assumes the skipped parameter has a width of 1 -- i.e. it is not
+        // If we get parameter names from MethodParameters, then we
+        // don't need to skip.
+        int firstParam = 0;
+        if (!sawMethodParameters) {
+            firstParam = ((sym.flags() & STATIC) == 0) ? 1 : 0;
+            // the code in readMethod may have skipped the first
+            // parameter when setting up the MethodType. If so, we
+            // make a corresponding allowance here for the position of
+            // the first parameter.  Note that this assumes the
+            // skipped parameter has a width of 1 -- i.e. it is not
         // a double width type (long or double.)
         if (sym.name == names.init && currentOwner.hasOuterInstance()) {
             // Sometimes anonymous classes don't have an outer
@@ -1861,17 +1892,20 @@
         }
 
         if (sym.type != jvmType) {
-            // reading the method attributes has caused the symbol's type to
-            // be changed. (i.e. the Signature attribute.)  This may happen if
-            // there are hidden (synthetic) parameters in the descriptor, but
-            // not in the Signature.  The position of these hidden parameters
-            // is unspecified; for now, assume they are at the beginning, and
-            // so skip over them. The primary case for this is two hidden
-            // parameters passed into Enum constructors.
+                // reading the method attributes has caused the
+                // symbol's type to be changed. (i.e. the Signature
+                // attribute.)  This may happen if there are hidden
+                // (synthetic) parameters in the descriptor, but not
+                // in the Signature.  The position of these hidden
+                // parameters is unspecified; for now, assume they are
+                // at the beginning, and so skip over them. The
+                // primary case for this is two hidden parameters
+                // passed into Enum constructors.
             int skip = Code.width(jvmType.getParameterTypes())
                     - Code.width(sym.type.getParameterTypes());
             firstParam += skip;
         }
+        }
         List<Name> paramNames = List.nil();
         int index = firstParam;
         for (Type t: sym.type.getParameterTypes()) {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Jan 16 11:58:15 2013 -0800
@@ -725,6 +725,28 @@
         return acount;
     }
 
+    /**
+     * Write method parameter names attribute.
+     */
+    int writeMethodParametersAttr(MethodSymbol m) {
+        if (m.params != null && 0 != m.params.length()) {
+            int attrIndex = writeAttr(names.MethodParameters);
+            databuf.appendByte(m.params.length());
+            for (VarSymbol s : m.params) {
+                // TODO: expand to cover synthesized, once we figure out
+                // how to represent that.
+                final int flags = (int) s.flags() & (FINAL | SYNTHETIC);
+                // output parameter info
+                databuf.appendChar(pool.put(s.name));
+                databuf.appendInt(flags);
+            }
+            endAttr(attrIndex);
+            return 1;
+        } else
+            return 0;
+    }
+
+
     /** Write method parameter annotations;
      *  return number of attributes written.
      */
@@ -1034,6 +1056,8 @@
             endAttr(alenIdx);
             acount++;
         }
+        if (options.isSet(PARAMETERS))
+            acount += writeMethodParametersAttr(m);
         acount += writeMemberAttrs(m);
         acount += writeParameterAttrs(m);
         endAttrs(acountIdx, acount);
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Option.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Option.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -176,6 +176,8 @@
 
     PROCESSORPATH("-processorpath", "opt.arg.path", "opt.processorpath", STANDARD, FILEMANAGER),
 
+    PARAMETERS("-parameters","opt.parameters", STANDARD, BASIC),
+
     D("-d", "opt.arg.directory", "opt.d", STANDARD, FILEMANAGER),
 
     S("-s", "opt.arg.directory", "opt.sourceDest", STANDARD, FILEMANAGER),
@@ -309,7 +311,7 @@
 
     // This option exists only for the purpose of documenting itself.
     // It's actually implemented by the launcher.
-    J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO) {
+    J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, true) {
         @Override
         public boolean process(OptionHelper helper, String option) {
             throw new AssertionError
@@ -414,7 +416,7 @@
 
     // This option exists only for the purpose of documenting itself.
     // It's actually implemented by the CommandLine class.
-    AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO) {
+    AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, true) {
         @Override
         public boolean process(OptionHelper helper, String option) {
             throw new AssertionError("the @ flag should be caught by CommandLine.");
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac.properties	Wed Jan 16 11:58:15 2013 -0800
@@ -55,6 +55,8 @@
     Specify where to find annotation processors
 javac.opt.processor=\
     Names of the annotation processors to run; bypasses default discovery process
+javac.opt.parameters=\
+    Generate metadata for reflection on method parameters
 javac.opt.proc.none.only=\
     Control whether annotation processing and/or compilation is done.
 javac.opt.d=\
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -154,12 +154,13 @@
         }
         //we need to (i) replace all line terminators with a space and (ii) remove
         //occurrences of 'missing' in the Pretty output (generated when types are missing)
-        String res = s.toString().replaceAll("\\s+", " ").replaceAll("/\\*missing\\*/", "");
+        String res = s.toString().trim().replaceAll("\\s+", " ").replaceAll("/\\*missing\\*/", "");
         if (res.length() < maxLength) {
             return res;
         } else {
-            int split = (maxLength - trimSequence.length()) * 2 / 3;
-            return res.substring(0, split) + trimSequence + res.substring(split);
+            int head = (maxLength - trimSequence.length()) * 2 / 3;
+            int tail = maxLength - trimSequence.length() - head;
+            return res.substring(0, head) + trimSequence + res.substring(res.length() - tail);
         }
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java	Wed Jan 16 11:58:15 2013 -0800
@@ -132,6 +132,7 @@
     public final Name LineNumberTable;
     public final Name LocalVariableTable;
     public final Name LocalVariableTypeTable;
+    public final Name MethodParameters;
     public final Name RuntimeInvisibleAnnotations;
     public final Name RuntimeInvisibleParameterAnnotations;
     public final Name RuntimeInvisibleTypeAnnotations;
@@ -265,6 +266,7 @@
         LineNumberTable = fromString("LineNumberTable");
         LocalVariableTable = fromString("LocalVariableTable");
         LocalVariableTypeTable = fromString("LocalVariableTypeTable");
+        MethodParameters = fromString("MethodParameters");
         RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
         RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
         RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java	Wed Jan 16 11:58:15 2013 -0800
@@ -89,6 +89,15 @@
     }
 
     /**
+     * Check for the synthesized bit on the annotation.
+     *
+     * @return true if the annotation is synthesized.
+     */
+    public boolean isSynthesized() {
+        return annotation.isSynthesized();
+    }
+
+    /**
      * Returns a string representation of this annotation.
      * String is of one of the forms:
      *     @com.example.foo(name1=val1, name2=val2)
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Messager.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -133,16 +133,6 @@
         this.programName = programName;
     }
 
-    @Override
-    protected int getDefaultMaxErrors() {
-        return Integer.MAX_VALUE;
-    }
-
-    @Override
-    protected int getDefaultMaxWarnings() {
-        return Integer.MAX_VALUE;
-    }
-
     public void setLocale(Locale locale) {
         this.locale = locale;
     }
--- a/langtools/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java	Wed Jan 16 11:58:15 2013 -0800
@@ -86,16 +86,7 @@
      * Return true if this method is abstract
      */
     public boolean isAbstract() {
-        //### This is dubious, but old 'javadoc' apparently does it.
-        //### I regard this as a bug and an obstacle to treating the
-        //### doclet API as a proper compile-time reflection facility.
-        //### (maddox 09/26/2000)
-        if (containingClass().isInterface()) {
-            //### Don't force creation of ClassDocImpl for super here.
-            // Abstract modifier is implicit.  Strip/canonicalize it.
-            return false;
-        }
-        return Modifier.isAbstract(getModifiers());
+        return (Modifier.isAbstract(getModifiers()) && !isDefault());
     }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@
 import com.sun.tools.classfile.LineNumberTable_attribute;
 import com.sun.tools.classfile.LocalVariableTable_attribute;
 import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
+import com.sun.tools.classfile.MethodParameters_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;
@@ -386,6 +387,28 @@
         return null;
     }
 
+    private static final String format = "%-31s%s";
+
+    public Void visitMethodParameters(MethodParameters_attribute attr,
+                                      Void ignore) {
+
+        final String header = String.format(format, "Name", "Flags");
+        println("MethodParameters:");
+        indent(+1);
+        println(header);
+        for (MethodParameters_attribute.Entry entry :
+                 attr.method_parameter_table) {
+            String flagstr =
+                (0 != (entry.flags & ACC_FINAL) ? " final" : "") +
+                (0 != (entry.flags & ACC_SYNTHETIC) ? " synthetic" : "");
+            println(String.format(format,
+                                  constantWriter.stringValue(entry.name_index),
+                                  flagstr));
+        }
+        indent(-1);
+        return null;
+    }
+
     public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
         println("RuntimeVisibleAnnotations:");
         indent(+1);
--- a/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -206,7 +206,7 @@
             println("minor version: " + cf.minor_version);
             println("major version: " + cf.major_version);
             if (!options.compat)
-              writeList("flags: ", flags.getClassFlags(), NEWLINE);
+              writeList("flags: ", flags.getClassFlags(), "\n");
             indent(-1);
             constantWriter.writeConstantPool();
         } else {
@@ -383,7 +383,7 @@
             println("Signature: " + getValue(f.descriptor));
 
         if (options.verbose && !options.compat)
-            writeList("flags: ", flags.getFieldFlags(), NEWLINE);
+            writeList("flags: ", flags.getFieldFlags(), "\n");
 
         if (options.showAllAttrs) {
             for (Attribute attr: f.attributes)
@@ -480,7 +480,7 @@
         }
 
         if (options.verbose && !options.compat) {
-            writeList("flags: ", flags.getMethodFlags(), NEWLINE);
+            writeList("flags: ", flags.getMethodFlags(), "\n");
         }
 
         Code_attribute code = null;
@@ -749,5 +749,4 @@
     private int size;
     private ConstantPool constant_pool;
     private Method method;
-    private static final String NEWLINE = System.getProperty("line.separator", "\n");
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Archive.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.jdeps;
+
+import com.sun.tools.classfile.Dependency;
+import com.sun.tools.classfile.Dependency.Location;
+import java.io.File;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/**
+ * Represents the source of the class files.
+ */
+public class Archive {
+    private static Map<String,Archive> archiveForClass = new HashMap<String,Archive>();
+    public static Archive find(Location loc) {
+        return archiveForClass.get(loc.getName());
+    }
+
+    private final File file;
+    private final String filename;
+    private final DependencyRecorder recorder;
+    private final ClassFileReader reader;
+    public Archive(String name) {
+        this.file = null;
+        this.filename = name;
+        this.recorder = new DependencyRecorder();
+        this.reader = null;
+    }
+
+    public Archive(File f, ClassFileReader reader) {
+        this.file = f;
+        this.filename = f.getName();
+        this.recorder = new DependencyRecorder();
+        this.reader = reader;
+    }
+
+    public ClassFileReader reader() {
+        return reader;
+    }
+
+    public String getFileName() {
+        return filename;
+    }
+
+    public void addClass(String classFileName) {
+        Archive a = archiveForClass.get(classFileName);
+        assert(a == null || a == this); // ## issue warning?
+        if (!archiveForClass.containsKey(classFileName)) {
+            archiveForClass.put(classFileName, this);
+        }
+    }
+
+    public void addDependency(Dependency d) {
+        recorder.addDependency(d);
+    }
+
+    /**
+     * Returns a sorted map of a class to its dependencies.
+     */
+    public SortedMap<Location, SortedSet<Location>> getDependencies() {
+        DependencyRecorder.Filter filter = new DependencyRecorder.Filter() {
+            public boolean accept(Location origin, Location target) {
+                 return (archiveForClass.get(origin.getName()) !=
+                            archiveForClass.get(target.getName()));
+        }};
+
+        SortedMap<Location, SortedSet<Location>> result =
+            new TreeMap<Location, SortedSet<Location>>(locationComparator);
+        for (Map.Entry<Location, Set<Location>> e : recorder.dependencies().entrySet()) {
+            Location o = e.getKey();
+            for (Location t : e.getValue()) {
+                if (filter.accept(o, t)) {
+                    SortedSet<Location> odeps = result.get(o);
+                    if (odeps == null) {
+                        odeps = new TreeSet<Location>(locationComparator);
+                        result.put(o, odeps);
+                    }
+                    odeps.add(t);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the set of archives this archive requires.
+     */
+    public Set<Archive> getRequiredArchives() {
+        SortedSet<Archive> deps = new TreeSet<Archive>(new Comparator<Archive>() {
+            public int compare(Archive a1, Archive a2) {
+                return a1.toString().compareTo(a2.toString());
+            }
+        });
+
+        for (Map.Entry<Location, Set<Location>> e : recorder.dependencies().entrySet()) {
+            Location o = e.getKey();
+            Archive origin = Archive.find(o);
+            for (Location t : e.getValue()) {
+                Archive target = Archive.find(t);
+                assert(origin != null && target != null);
+                if (origin != target) {
+                    if (!deps.contains(target)) {
+                        deps.add(target);
+                    }
+                }
+            }
+        }
+        return deps;
+    }
+
+    public String toString() {
+        return file != null ? file.getPath() : filename;
+    }
+
+    private static class DependencyRecorder {
+        static interface Filter {
+            boolean accept(Location origin, Location target);
+        }
+
+        public void addDependency(Dependency d) {
+            Set<Location> odeps = map.get(d.getOrigin());
+            if (odeps == null) {
+                odeps = new HashSet<Location>();
+                map.put(d.getOrigin(), odeps);
+            }
+            odeps.add(d.getTarget());
+        }
+
+        public Map<Location, Set<Location>> dependencies() {
+            return map;
+        }
+
+        private final Map<Location, Set<Location>> map =
+            new HashMap<Location, Set<Location>>();
+    }
+
+    private static Comparator<Location> locationComparator =
+        new Comparator<Location>() {
+            public int compare(Location o1, Location o2) {
+                return o1.toString().compareTo(o2.toString());
+            }
+        };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.jdeps;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Dependencies.ClassFileError;
+import java.io.*;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * ClassFileReader reads ClassFile(s) of a given path that can be
+ * a .class file, a directory, or a JAR file.
+ */
+public class ClassFileReader {
+    /**
+     * Returns a ClassFileReader instance of a given path.
+     */
+    public static ClassFileReader newInstance(File path) throws IOException {
+        if (!path.exists()) {
+            throw new FileNotFoundException(path.getAbsolutePath());
+        }
+
+        if (path.isDirectory()) {
+            return new DirectoryReader(path.toPath());
+        } else if (path.getName().endsWith(".jar")) {
+            return new JarFileReader(path.toPath());
+        } else {
+            return new ClassFileReader(path.toPath());
+        }
+    }
+
+    protected final Path path;
+    protected final String baseFileName;
+    private ClassFileReader(Path path) {
+        this.path = path;
+        this.baseFileName = path.getFileName() != null
+                                ? path.getFileName().toString()
+                                : path.toString();
+    }
+
+    public String getFileName() {
+        return baseFileName;
+    }
+
+    /**
+     * Returns the ClassFile matching the given binary name
+     * or a fully-qualified class name.
+     */
+    public ClassFile getClassFile(String name) throws IOException {
+        if (name.indexOf('.') > 0) {
+            int i = name.lastIndexOf('.');
+            String pathname = name.replace('.', File.separatorChar) + ".class";
+            if (baseFileName.equals(pathname) ||
+                    baseFileName.equals(pathname.substring(0, i) + "$" +
+                                        pathname.substring(i+1, pathname.length()))) {
+                return readClassFile(path);
+            }
+        } else {
+            if (baseFileName.equals(name.replace('/', File.separatorChar) + ".class")) {
+                return readClassFile(path);
+            }
+        }
+        return null;
+    }
+
+    public Iterable<ClassFile> getClassFiles() throws IOException {
+        return new Iterable<ClassFile>() {
+            public Iterator<ClassFile> iterator() {
+                return new FileIterator();
+            }
+        };
+    }
+
+    protected ClassFile readClassFile(Path p) throws IOException {
+        InputStream is = null;
+        try {
+            is = Files.newInputStream(p);
+            return ClassFile.read(is);
+        } catch (ConstantPoolException e) {
+            throw new ClassFileError(e);
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+        }
+    }
+
+    class FileIterator implements Iterator<ClassFile> {
+        int count;
+        FileIterator() {
+            this.count = 0;
+        }
+        public boolean hasNext() {
+            return count == 0 && baseFileName.endsWith(".class");
+        }
+
+        public ClassFile next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            try {
+                ClassFile cf = readClassFile(path);
+                count++;
+                return cf;
+            } catch (IOException e) {
+                throw new ClassFileError(e);
+            }
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+
+    public String toString() {
+        return path.toString();
+    }
+
+    private static class DirectoryReader extends ClassFileReader {
+        DirectoryReader(Path path) throws IOException {
+            super(path);
+        }
+
+        public ClassFile getClassFile(String name) throws IOException {
+            if (name.indexOf('.') > 0) {
+                int i = name.lastIndexOf('.');
+                String pathname = name.replace('.', File.separatorChar) + ".class";
+                Path p = path.resolve(pathname);
+                if (!p.toFile().exists()) {
+                    p = path.resolve(pathname.substring(0, i) + "$" +
+                                     pathname.substring(i+1, pathname.length()));
+                }
+                if (p.toFile().exists()) {
+                    return readClassFile(p);
+                }
+            } else {
+                Path p = path.resolve(name + ".class");
+                if (p.toFile().exists()) {
+                    return readClassFile(p);
+                }
+            }
+            return null;
+        }
+
+        public Iterable<ClassFile> getClassFiles() throws IOException {
+            final Iterator<ClassFile> iter = new DirectoryIterator();
+            return new Iterable<ClassFile>() {
+                public Iterator<ClassFile> iterator() {
+                    return iter;
+                }
+            };
+        }
+
+        private List<Path> walkTree(Path dir) throws IOException {
+            final List<Path> files = new ArrayList<Path>();
+            Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                        throws IOException {
+                    if (file.toFile().getName().endsWith(".class")) {
+                        files.add(file);
+                    }
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+            return files;
+        }
+
+        class DirectoryIterator implements Iterator<ClassFile> {
+            private List<Path> entries;
+            private int index = 0;
+            DirectoryIterator() throws IOException {
+                entries = walkTree(path);
+                index = 0;
+            }
+
+            public boolean hasNext() {
+                return index != entries.size();
+            }
+
+            public ClassFile next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+                Path path = entries.get(index++);
+                try {
+                    return readClassFile(path);
+                } catch (IOException e) {
+                    throw new ClassFileError(e);
+                }
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+        }
+    }
+
+    private static class JarFileReader extends ClassFileReader {
+        final JarFile jarfile;
+        JarFileReader(Path path) throws IOException {
+            super(path);
+            this.jarfile = new JarFile(path.toFile());
+        }
+
+        public ClassFile getClassFile(String name) throws IOException {
+            if (name.indexOf('.') > 0) {
+                int i = name.lastIndexOf('.');
+                String entryName = name.replace('.', '/') + ".class";
+                JarEntry e = jarfile.getJarEntry(entryName);
+                if (e == null) {
+                    e = jarfile.getJarEntry(entryName.substring(0, i) + "$"
+                            + entryName.substring(i + 1, entryName.length()));
+                }
+                if (e != null) {
+                    return readClassFile(e);
+                }
+            } else {
+                JarEntry e = jarfile.getJarEntry(name + ".class");
+                if (e != null) {
+                    return readClassFile(e);
+                }
+            }
+            return null;
+        }
+
+        private ClassFile readClassFile(JarEntry e) throws IOException {
+            InputStream is = null;
+            try {
+                is = jarfile.getInputStream(e);
+                return ClassFile.read(is);
+            } catch (ConstantPoolException ex) {
+                throw new ClassFileError(ex);
+            } finally {
+                if (is != null)
+                    is.close();
+            }
+        }
+
+        public Iterable<ClassFile> getClassFiles() throws IOException {
+            final Iterator<ClassFile> iter = new JarFileIterator();
+            return new Iterable<ClassFile>() {
+                public Iterator<ClassFile> iterator() {
+                    return iter;
+                }
+            };
+        }
+
+        class JarFileIterator implements Iterator<ClassFile> {
+            private Enumeration<JarEntry> entries;
+            private JarEntry nextEntry;
+            JarFileIterator() {
+                this.entries = jarfile.entries();
+                while (entries.hasMoreElements()) {
+                    JarEntry e = entries.nextElement();
+                    String name = e.getName();
+                    if (name.endsWith(".class")) {
+                        this.nextEntry = e;
+                        break;
+                    }
+                }
+            }
+
+            public boolean hasNext() {
+                return nextEntry != null;
+            }
+
+            public ClassFile next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+
+                ClassFile cf;
+                try {
+                    cf = readClassFile(nextEntry);
+                } catch (IOException ex) {
+                    throw new ClassFileError(ex);
+                }
+                JarEntry entry = nextEntry;
+                nextEntry = null;
+                while (entries.hasMoreElements()) {
+                    JarEntry e = entries.nextElement();
+                    String name = e.getName();
+                    if (name.endsWith(".class")) {
+                        nextEntry = e;
+                        break;
+                    }
+                }
+                return cf;
+            }
+
+            public void remove() {
+                throw new UnsupportedOperationException("Not supported yet.");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,650 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.jdeps;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Dependencies;
+import com.sun.tools.classfile.Dependencies.ClassFileError;
+import com.sun.tools.classfile.Dependency;
+import com.sun.tools.classfile.Dependency.Location;
+import java.io.*;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * Implementation for the jdeps tool for static class dependency analysis.
+ */
+class JdepsTask {
+    class BadArgs extends Exception {
+        static final long serialVersionUID = 8765093759964640721L;
+        BadArgs(String key, Object... args) {
+            super(JdepsTask.this.getMessage(key, args));
+            this.key = key;
+            this.args = args;
+        }
+
+        BadArgs showUsage(boolean b) {
+            showUsage = b;
+            return this;
+        }
+        final String key;
+        final Object[] args;
+        boolean showUsage;
+    }
+
+    static abstract class Option {
+        Option(boolean hasArg, String... aliases) {
+            this.hasArg = hasArg;
+            this.aliases = aliases;
+        }
+
+        boolean isHidden() {
+            return false;
+        }
+
+        boolean matches(String opt) {
+            for (String a : aliases) {
+                if (a.equals(opt)) {
+                    return true;
+                } else if (opt.startsWith("--") && hasArg && opt.startsWith(a + "=")) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        boolean ignoreRest() {
+            return false;
+        }
+
+        abstract void process(JdepsTask task, String opt, String arg) throws BadArgs;
+        final boolean hasArg;
+        final String[] aliases;
+    }
+
+    static abstract class HiddenOption extends Option {
+        HiddenOption(boolean hasArg, String... aliases) {
+            super(hasArg, aliases);
+        }
+
+        boolean isHidden() {
+            return true;
+        }
+    }
+
+    static Option[] recognizedOptions = {
+        new Option(false, "-h", "-?", "--help") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.help = true;
+            }
+        },
+        new Option(false, "-s", "--summary") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.showSummary = true;
+                task.options.verbose = Options.Verbose.SUMMARY;
+            }
+        },
+        new Option(false, "-v", "--verbose") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.verbose = Options.Verbose.VERBOSE;
+            }
+        },
+        new Option(true, "-V", "--verbose-level") {
+            void process(JdepsTask task, String opt, String arg) throws BadArgs {
+                switch (arg) {
+                    case "package":
+                        task.options.verbose = Options.Verbose.PACKAGE;
+                        break;
+                    case "class":
+                        task.options.verbose = Options.Verbose.CLASS;
+                        break;
+                    default:
+                        throw task.new BadArgs("err.invalid.arg.for.option", opt);
+                }
+            }
+        },
+        new Option(true, "-c", "--classpath") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.classpath = arg;
+            }
+        },
+        new Option(true, "-p", "--package") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.packageNames.add(arg);
+            }
+        },
+        new Option(true, "-e", "--regex") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.regex = arg;
+            }
+        },
+        new Option(false, "-P", "--profile") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.showProfile = true;
+            }
+        },
+        new Option(false, "-R", "--recursive") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.depth = 0;
+            }
+        },
+        new HiddenOption(true, "-d", "--depth") {
+            void process(JdepsTask task, String opt, String arg) throws BadArgs {
+                try {
+                    task.options.depth = Integer.parseInt(arg);
+                } catch (NumberFormatException e) {
+                    throw task.new BadArgs("err.invalid.arg.for.option", opt);
+                }
+            }
+        },
+        new Option(false, "--version") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.version = true;
+            }
+        },
+        new HiddenOption(false, "--fullversion") {
+            void process(JdepsTask task, String opt, String arg) {
+                task.options.fullVersion = true;
+            }
+        },
+
+    };
+
+    private static final String PROGNAME = "jdeps";
+    private final Options options = new Options();
+    private final List<String> classes = new ArrayList<String>();
+
+    private PrintWriter log;
+    void setLog(PrintWriter out) {
+        log = out;
+    }
+
+    /**
+     * Result codes.
+     */
+    static final int EXIT_OK = 0, // Completed with no errors.
+                     EXIT_ERROR = 1, // Completed but reported errors.
+                     EXIT_CMDERR = 2, // Bad command-line arguments
+                     EXIT_SYSERR = 3, // System error or resource exhaustion.
+                     EXIT_ABNORMAL = 4;// terminated abnormally
+
+    int run(String[] args) {
+        if (log == null) {
+            log = new PrintWriter(System.out);
+        }
+        try {
+            handleOptions(args);
+            if (options.help) {
+                showHelp();
+            }
+            if (options.version || options.fullVersion) {
+                showVersion(options.fullVersion);
+            }
+            if (classes.isEmpty() && !options.wildcard) {
+                if (options.help || options.version || options.fullVersion) {
+                    return EXIT_OK;
+                } else {
+                    showHelp();
+                    return EXIT_CMDERR;
+                }
+            }
+            if (options.regex != null && options.packageNames.size() > 0) {
+                showHelp();
+                return EXIT_CMDERR;
+            }
+            if (options.showSummary && options.verbose != Options.Verbose.SUMMARY) {
+                showHelp();
+                return EXIT_CMDERR;
+            }
+            boolean ok = run();
+            return ok ? EXIT_OK : EXIT_ERROR;
+        } catch (BadArgs e) {
+            reportError(e.key, e.args);
+            if (e.showUsage) {
+                log.println(getMessage("main.usage.summary", PROGNAME));
+            }
+            return EXIT_CMDERR;
+        } catch (IOException e) {
+            return EXIT_ABNORMAL;
+        } finally {
+            log.flush();
+        }
+    }
+
+    private final List<Archive> sourceLocations = new ArrayList<Archive>();
+    private final Archive NOT_FOUND = new Archive(getMessage("artifact.not.found"));
+    private boolean run() throws IOException {
+        findDependencies();
+        switch (options.verbose) {
+            case VERBOSE:
+            case CLASS:
+                printClassDeps(log);
+                break;
+            case PACKAGE:
+                printPackageDeps(log);
+                break;
+            case SUMMARY:
+                for (Archive origin : sourceLocations) {
+                    for (Archive target : origin.getRequiredArchives()) {
+                        log.format("%-30s -> %s%n", origin, target);
+                    }
+                }
+                break;
+            default:
+                throw new InternalError("Should not reach here");
+        }
+        return true;
+    }
+
+    private boolean isValidClassName(String name) {
+        if (!Character.isJavaIdentifierStart(name.charAt(0))) {
+            return false;
+        }
+        for (int i=1; i < name.length(); i++) {
+            char c = name.charAt(i);
+            if (c != '.'  && !Character.isJavaIdentifierPart(c)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void findDependencies() throws IOException {
+        Dependency.Finder finder = Dependencies.getClassDependencyFinder();
+        Dependency.Filter filter;
+        if (options.regex != null) {
+            filter = Dependencies.getRegexFilter(Pattern.compile(options.regex));
+        } else if (options.packageNames.size() > 0) {
+            filter = Dependencies.getPackageFilter(options.packageNames, false);
+        } else {
+            filter = new Dependency.Filter() {
+                public boolean accepts(Dependency dependency) {
+                    return !dependency.getOrigin().equals(dependency.getTarget());
+                }
+            };
+        }
+
+        List<Archive> archives = new ArrayList<Archive>();
+        Deque<String> roots = new LinkedList<String>();
+        for (String s : classes) {
+            File f = new File(s);
+            if (f.exists()) {
+                archives.add(new Archive(f, ClassFileReader.newInstance(f)));
+            } else {
+                if (isValidClassName(s)) {
+                    roots.add(s);
+                } else {
+                    warning("warn.invalid.arg", s);
+                }
+            }
+        }
+
+        List<Archive> classpaths = new ArrayList<Archive>(); // for class file lookup
+        if (options.wildcard) {
+            // include all archives from classpath to the initial list
+            archives.addAll(getClassPathArchives(options.classpath));
+        } else {
+            classpaths.addAll(getClassPathArchives(options.classpath));
+        }
+        classpaths.addAll(PlatformClassPath.getArchives());
+
+        // add all archives to the source locations for reporting
+        sourceLocations.addAll(archives);
+        sourceLocations.addAll(classpaths);
+
+        // Work queue of names of classfiles to be searched.
+        // Entries will be unique, and for classes that do not yet have
+        // dependencies in the results map.
+        Deque<String> deque = new LinkedList<String>();
+        Set<String> doneClasses = new HashSet<String>();
+
+        // get the immediate dependencies of the input files
+        for (Archive a : archives) {
+            for (ClassFile cf : a.reader().getClassFiles()) {
+                String classFileName;
+                try {
+                    classFileName = cf.getName();
+                } catch (ConstantPoolException e) {
+                    throw new ClassFileError(e);
+                }
+                a.addClass(classFileName);
+                if (!doneClasses.contains(classFileName)) {
+                    doneClasses.add(classFileName);
+                }
+                for (Dependency d : finder.findDependencies(cf)) {
+                    if (filter.accepts(d)) {
+                        String cn = d.getTarget().getName();
+                        if (!doneClasses.contains(cn) && !deque.contains(cn)) {
+                            deque.add(cn);
+                        }
+                        a.addDependency(d);
+                    }
+                }
+            }
+        }
+
+        // add Archive for looking up classes from the classpath
+        // for transitive dependency analysis
+        Deque<String> unresolved = roots;
+        int depth = options.depth > 0 ? options.depth : Integer.MAX_VALUE;
+        do {
+            String name;
+            while ((name = unresolved.poll()) != null) {
+                if (doneClasses.contains(name)) {
+                    continue;
+                }
+                ClassFile cf = null;
+                for (Archive a : classpaths) {
+                    cf = a.reader().getClassFile(name);
+                    if (cf != null) {
+                        String classFileName;
+                        try {
+                            classFileName = cf.getName();
+                        } catch (ConstantPoolException e) {
+                            throw new ClassFileError(e);
+                        }
+                        a.addClass(classFileName);
+                        if (!doneClasses.contains(classFileName)) {
+                            // if name is a fully-qualified class name specified
+                            // from command-line, this class might already be parsed
+                            doneClasses.add(classFileName);
+                            if (depth > 0) {
+                                for (Dependency d : finder.findDependencies(cf)) {
+                                    if (filter.accepts(d)) {
+                                        String cn = d.getTarget().getName();
+                                        if (!doneClasses.contains(cn) && !deque.contains(cn)) {
+                                            deque.add(cn);
+                                        }
+                                        a.addDependency(d);
+                                    }
+                                }
+                            }
+                        }
+                        break;
+                    }
+                }
+                if (cf == null) {
+                    NOT_FOUND.addClass(name);
+                }
+            }
+            unresolved = deque;
+            deque = new LinkedList<String>();
+        } while (!unresolved.isEmpty() && depth-- > 0);
+    }
+
+    private void printPackageDeps(PrintWriter out) {
+        for (Archive source : sourceLocations) {
+            SortedMap<Location, SortedSet<Location>> deps = source.getDependencies();
+            if (deps.isEmpty())
+                continue;
+
+            for (Archive target : source.getRequiredArchives()) {
+                out.format("%s -> %s%n", source, target);
+            }
+
+            Map<String, Archive> pkgs = new TreeMap<String, Archive>();
+            SortedMap<String, Archive> targets = new TreeMap<String, Archive>();
+            String pkg = "";
+            for (Map.Entry<Location, SortedSet<Location>> e : deps.entrySet()) {
+                String cn = e.getKey().getClassName();
+                String p = packageOf(e.getKey());
+                Archive origin = Archive.find(e.getKey());
+                assert origin != null;
+                if (!pkgs.containsKey(p)) {
+                    pkgs.put(p, origin);
+                } else if (pkgs.get(p) != origin) {
+                    warning("warn.split.package", p, origin, pkgs.get(p));
+                }
+
+                if (!p.equals(pkg)) {
+                    printTargets(out, targets);
+                    pkg = p;
+                    targets.clear();
+                    out.format("   %s (%s)%n", p, origin.getFileName());
+                }
+
+                for (Location t : e.getValue()) {
+                    p = packageOf(t);
+                    Archive target = Archive.find(t);
+                    if (!targets.containsKey(p)) {
+                        targets.put(p, target);
+                    }
+                }
+            }
+            printTargets(out, targets);
+            out.println();
+        }
+    }
+
+    private void printTargets(PrintWriter out, Map<String, Archive> targets) {
+        for (Map.Entry<String, Archive> t : targets.entrySet()) {
+            String pn = t.getKey();
+            out.format("      -> %-40s %s%n", pn, getPackageInfo(pn, t.getValue()));
+        }
+    }
+
+    private String getPackageInfo(String pn, Archive source) {
+        if (PlatformClassPath.contains(source)) {
+            String name = PlatformClassPath.getProfileName(pn);
+            if (name.isEmpty()) {
+                return "JDK internal API (" + source.getFileName() + ")";
+            }
+            return options.showProfile ? name : "";
+        }
+        return source.getFileName();
+    }
+
+    private static String packageOf(Location loc) {
+        String pkg = loc.getPackageName();
+        return pkg.isEmpty() ? "<unnamed>" : pkg;
+    }
+
+    private void printClassDeps(PrintWriter out) {
+        for (Archive source : sourceLocations) {
+            SortedMap<Location, SortedSet<Location>> deps = source.getDependencies();
+            if (deps.isEmpty())
+                continue;
+
+            for (Archive target : source.getRequiredArchives()) {
+                out.format("%s -> %s%n", source, target);
+            }
+            out.format("%s%n", source);
+            for (Map.Entry<Location, SortedSet<Location>> e : deps.entrySet()) {
+                String cn = e.getKey().getClassName();
+                Archive origin = Archive.find(e.getKey());
+                out.format("   %s (%s)%n", cn, origin.getFileName());
+                for (Location t : e.getValue()) {
+                    cn = t.getClassName();
+                    Archive target = Archive.find(t);
+                    out.format("      -> %-60s %s%n", cn, getPackageInfo(t.getPackageName(), target));
+                }
+            }
+            out.println();
+        }
+    }
+    public void handleOptions(String[] args) throws BadArgs {
+        // process options
+        for (int i=0; i < args.length; i++) {
+            if (args[i].charAt(0) == '-') {
+                String name = args[i];
+                Option option = getOption(name);
+                String param = null;
+                if (option.hasArg) {
+                    if (name.startsWith("--") && name.indexOf('=') > 0) {
+                        param = name.substring(name.indexOf('=') + 1, name.length());
+                    } else if (i + 1 < args.length) {
+                        param = args[++i];
+                    }
+                    if (param == null || param.isEmpty() || param.charAt(0) == '-') {
+                        throw new BadArgs("err.missing.arg", name).showUsage(true);
+                    }
+                }
+                option.process(this, name, param);
+                if (option.ignoreRest()) {
+                    i = args.length;
+                }
+            } else {
+                // process rest of the input arguments
+                for (; i < args.length; i++) {
+                    String name = args[i];
+                    if (name.charAt(0) == '-') {
+                        throw new BadArgs("err.option.after.class", name).showUsage(true);
+                    }
+                    if (name.equals("*") || name.equals("\"*\"")) {
+                        options.wildcard = true;
+                    } else {
+                        classes.add(name);
+                    }
+                }
+            }
+        }
+    }
+
+    private Option getOption(String name) throws BadArgs {
+        for (Option o : recognizedOptions) {
+            if (o.matches(name)) {
+                return o;
+            }
+        }
+        throw new BadArgs("err.unknown.option", name).showUsage(true);
+    }
+
+    private void reportError(String key, Object... args) {
+        log.println(getMessage("error.prefix") + " " + getMessage(key, args));
+    }
+
+    private void warning(String key, Object... args) {
+        log.println(getMessage("warn.prefix") + " " + getMessage(key, args));
+    }
+
+    private void showHelp() {
+        log.println(getMessage("main.usage", PROGNAME));
+        for (Option o : recognizedOptions) {
+            String name = o.aliases[0].substring(1); // there must always be at least one name
+            name = name.charAt(0) == '-' ? name.substring(1) : name;
+            if (o.isHidden() || name.equals("h")) {
+                continue;
+            }
+            log.println(getMessage("main.opt." + name));
+        }
+    }
+
+    private void showVersion(boolean full) {
+        log.println(version(full ? "full" : "release"));
+    }
+
+    private String version(String key) {
+        // key=version:  mm.nn.oo[-milestone]
+        // key=full:     mm.mm.oo[-milestone]-build
+        if (ResourceBundleHelper.versionRB == null) {
+            return System.getProperty("java.version");
+        }
+        try {
+            return ResourceBundleHelper.versionRB.getString(key);
+        } catch (MissingResourceException e) {
+            return getMessage("version.unknown", System.getProperty("java.version"));
+        }
+    }
+
+    public String getMessage(String key, Object... args) {
+        try {
+            return MessageFormat.format(ResourceBundleHelper.bundle.getString(key), args);
+        } catch (MissingResourceException e) {
+            throw new InternalError("Missing message: " + key);
+        }
+    }
+
+    private static class Options {
+        enum Verbose {
+            CLASS,
+            PACKAGE,
+            SUMMARY,
+            VERBOSE
+        };
+
+        boolean help;
+        boolean version;
+        boolean fullVersion;
+        boolean showFlags;
+        boolean showProfile;
+        boolean showSummary;
+        boolean wildcard;
+        String regex;
+        String classpath = "";
+        int depth = 1;
+        Verbose verbose = Verbose.PACKAGE;
+        Set<String> packageNames = new HashSet<String>();
+    }
+
+    private static class ResourceBundleHelper {
+        static final ResourceBundle versionRB;
+        static final ResourceBundle bundle;
+
+        static {
+            Locale locale = Locale.getDefault();
+            try {
+                bundle = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdeps", locale);
+            } catch (MissingResourceException e) {
+                throw new InternalError("Cannot find jdeps resource bundle for locale " + locale);
+            }
+            try {
+                versionRB = ResourceBundle.getBundle("com.sun.tools.jdeps.resources.version");
+            } catch (MissingResourceException e) {
+                throw new InternalError("version.resource.missing");
+            }
+        }
+    }
+
+    private List<Archive> getArchives(List<String> filenames) throws IOException {
+        List<Archive> result = new ArrayList<Archive>();
+        for (String s : filenames) {
+            File f = new File(s);
+            if (f.exists()) {
+                result.add(new Archive(f, ClassFileReader.newInstance(f)));
+            } else {
+                warning("warn.file.not.exist", s);
+            }
+        }
+        return result;
+    }
+
+    private List<Archive> getClassPathArchives(String paths) throws IOException {
+        List<Archive> result = new ArrayList<Archive>();
+        if (paths.isEmpty()) {
+            return result;
+        }
+        for (String p : paths.split(File.pathSeparator)) {
+            if (p.length() > 0) {
+                File f = new File(p);
+                if (f.exists()) {
+                    result.add(new Archive(f, ClassFileReader.newInstance(f)));
+                }
+            }
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Main.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.jdeps;
+
+import java.io.*;
+
+/**
+ *
+ * Usage:
+ *    jdeps [options] files ...
+ * where options include:
+ *    -p package-name   restrict analysis to classes in this package
+ *                      (may be given multiple times)
+ *    -e regex          restrict analysis to packages matching pattern
+ *                      (-p and -e are exclusive)
+ *    -v                show class-level dependencies
+ *                      default: package-level dependencies
+ *    -r --recursive    transitive dependencies analysis
+ *    -classpath paths  Classpath to locate class files
+ *    -all              process all class files in the given classpath
+ */
+public class Main {
+    public static void main(String... args) throws Exception {
+        JdepsTask t = new JdepsTask();
+        int rc = t.run(args);
+        System.exit(rc);
+    }
+
+
+    /**
+     * Entry point that does <i>not</i> call System.exit.
+     *
+     * @param args command line arguments
+     * @param out output stream
+     * @return an exit code. 0 means success, non-zero means an error occurred.
+     */
+    public static int run(String[] args, PrintWriter out) {
+        JdepsTask t = new JdepsTask();
+        t.setLog(out);
+        return t.run(args);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.jdeps;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.*;
+
+/**
+ * ClassPath for Java SE and JDK
+ */
+class PlatformClassPath {
+    /*
+     * Profiles for Java SE
+     *
+     * This is a temporary workaround until a common API is defined for langtools
+     * to determine which profile a given classname belongs to.  The list of
+     * packages and profile names are hardcoded in jdk.properties and
+     * split packages are not supported.
+     */
+    static class Profile {
+        final String name;
+        final Set<String> packages;
+
+        Profile(String name) {
+            this.name = name;
+            this.packages = new HashSet<String>();
+        }
+    }
+
+    private final static String JAVAFX = "javafx";
+    private final static Map<String,Profile> map = getProfilePackages();
+    static String getProfileName(String packageName) {
+        Profile profile = map.get(packageName);
+        if (packageName.startsWith(JAVAFX + ".")) {
+            profile = map.get(JAVAFX);
+        }
+        return profile != null ? profile.name : "";
+    }
+
+    private final static List<Archive> javaHomeArchives = init();
+    static List<Archive> getArchives() {
+        return javaHomeArchives;
+    }
+
+    static boolean contains(Archive archive) {
+        return javaHomeArchives.contains(archive);
+    }
+
+    private static List<Archive> init() {
+        List<Archive> result = new ArrayList<Archive>();
+        String javaHome = System.getProperty("java.home");
+        List<File> files = new ArrayList<File>();
+        File jre = new File(javaHome, "jre");
+        File lib = new File(javaHome, "lib");
+
+        try {
+            if (jre.exists() && jre.isDirectory()) {
+                result.addAll(addJarFiles(new File(jre, "lib")));
+                result.addAll(addJarFiles(lib));
+            } else if (lib.exists() && lib.isDirectory()) {
+                // either a JRE or a jdk build image
+                File classes = new File(javaHome, "classes");
+                if (classes.exists() && classes.isDirectory()) {
+                    // jdk build outputdir
+                    result.add(new Archive(classes, ClassFileReader.newInstance(classes)));
+                }
+                // add other JAR files
+                result.addAll(addJarFiles(lib));
+            } else {
+                throw new RuntimeException("\"" + javaHome + "\" not a JDK home");
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        // add a JavaFX profile if there is jfxrt.jar
+        for (Archive archive : result) {
+            if (archive.getFileName().equals("jfxrt.jar")) {
+                map.put(JAVAFX, new Profile("jfxrt.jar"));
+            }
+        }
+        return result;
+    }
+
+    private static List<Archive> addJarFiles(File f) throws IOException {
+        final List<Archive> result = new ArrayList<Archive>();
+        final Path root = f.toPath();
+        final Path ext = root.resolve("ext");
+        Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+                throws IOException
+            {
+                if (dir.equals(root) || dir.equals(ext)) {
+                    return FileVisitResult.CONTINUE;
+                } else {
+                    // skip other cobundled JAR files
+                    return FileVisitResult.SKIP_SUBTREE;
+                }
+            }
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                throws IOException
+            {
+                File f = file.toFile();
+                String fn = f.getName();
+                if (fn.endsWith(".jar") && !fn.equals("alt-rt.jar")) {
+                    result.add(new Archive(f, ClassFileReader.newInstance(f)));
+                }
+                return FileVisitResult.CONTINUE;
+            }
+        });
+        return result;
+    }
+
+    private static Map<String,Profile> getProfilePackages() {
+        Map<String,Profile> map = new HashMap<String,Profile>();
+
+        // read the properties as a ResourceBundle as the build compiles
+        // the properties file into Java class.  Another alternative is
+        // to load it as Properties and fix the build to exclude this file.
+        ResourceBundle profileBundle =
+            ResourceBundle.getBundle("com.sun.tools.jdeps.resources.jdk");
+
+        int i=1;
+        String key;
+        while (profileBundle.containsKey((key = "profile." + i + ".name"))) {
+            Profile profile = new Profile(profileBundle.getString(key));
+            String n = profileBundle.getString("profile." + i + ".packages");
+            String[] pkgs = n.split("\\s+");
+            for (String p : pkgs) {
+                if (p.isEmpty()) continue;
+                assert(map.containsKey(p) == false);
+                profile.packages.add(p);
+                map.put(p, profile);
+            }
+            i++;
+        }
+        return map;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,57 @@
+main.usage.summary=\
+Usage: {0} <options> <classes...>\n\
+use -h, -? or --help for a list of possible options
+
+main.usage=\
+Usage: {0} <options> <classes...>\n\
+where <classes> can be a pathname to a .class file, a directory, a JAR file,\n\
+or a fully-qualified classname or wildcard "*".  Possible options include:
+
+error.prefix=Error:
+warn.prefix=Warning:
+
+main.opt.h=\
+\  -h -?      --help                    Print this usage message
+
+main.opt.version=\
+\             --version                 Version information
+
+main.opt.V=\
+\  -V <level> --verbose-level=<level>   Print package-level or class-level dependencies\n\
+\                                       Valid levels are: "package" and "class"
+
+main.opt.v=\
+\  -v         --verbose                 Print additional information
+
+main.opt.s=\
+\  -s         --summary                 Print dependency summary only
+
+main.opt.p=\
+\  -p <pkg name> --package=<pkg name>   Restrict analysis to classes in this package\n\
+\                                       (may be given multiple times)
+
+main.opt.e=\
+\  -e <regex> --regex=<regex>           Restrict analysis to packages matching pattern\n\
+\                                       (-p and -e are exclusive)
+
+main.opt.P=\
+\  -P         --profile                 Show profile or the file containing a package
+
+main.opt.c=\
+\  -c <path>  --classpath=<path>        Specify where to find class files
+
+main.opt.R=\
+\  -R         --recursive               Recursively traverse all dependencies
+
+main.opt.d=\
+\  -d <depth> --depth=<depth>           Specify the depth of the transitive dependency analysis
+
+err.unknown.option=unknown option: {0}
+err.missing.arg=no value given for {0}
+err.internal.error=internal error: {0} {1} {2}
+err.invalid.arg.for.option=invalid argument for option: {0}
+err.option.after.class=option must be specified before classes: {0}
+warn.invalid.arg=Invalid classname or pathname not exist: {0}
+warn.split.package=package {0} defined in {1} {2}
+
+artifact.not.found=not found
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdk.properties	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,262 @@
+# This properties file does not need localization.
+
+profile.1.name = compact1
+profile.1.packages = \
+    java.io \
+    java.lang \
+    java.lang.annotation \
+    java.lang.invoke \
+    java.lang.ref \
+    java.lang.reflect \
+    java.math \
+    java.net \
+    java.nio \
+    java.nio.channels \
+    java.nio.channels.spi \
+    java.nio.charset \
+    java.nio.charset.spi \
+    java.nio.file \
+    java.nio.file.attribute \
+    java.nio.file.spi \
+    java.security \
+    java.security.cert \
+    java.security.interfaces \
+    java.security.spec \
+    java.text \
+    java.text.spi \
+    java.util \
+    java.util.concurrent \
+    java.util.concurrent.atomic \
+    java.util.concurrent.locks \
+    java.util.jar \
+    java.util.logging \
+    java.util.regex \
+    java.util.spi \
+    java.util.zip \
+    javax.crypto \
+    javax.crypto.interfaces \
+    javax.crypto.spec \
+    javax.security.auth \
+    javax.security.auth.callback \
+    javax.security.auth.login \
+    javax.security.auth.spi \
+    javax.security.auth.x500 \
+    javax.net \
+    javax.net.ssl \
+    javax.security.cert \
+    \
+    com.sun.net.ssl \
+    com.sun.nio.file \
+    com.sun.nio.sctp \
+    com.sun.security.auth \
+    com.sun.security.auth.login
+
+profile.2.name = compact2
+profile.2.packages = \
+    java.sql \
+    javax.sql \
+    javax.xml \
+    javax.xml.datatype \
+    javax.xml.namespace \
+    javax.xml.parsers \
+    javax.xml.stream \
+    javax.xml.stream.events \
+    javax.xml.stream.util \
+    javax.xml.transform \
+    javax.xml.transform.dom \
+    javax.xml.transform.sax \
+    javax.xml.transform.stax \
+    javax.xml.transform.stream \
+    javax.xml.validation \
+    javax.xml.xpath \
+    org.w3c.dom \
+    org.w3c.dom.bootstrap \
+    org.w3c.dom.events \
+    org.w3c.dom.ls \
+    org.xml.sax \
+    org.xml.sax.ext \
+    org.xml.sax.helpers \
+    java.rmi \
+    java.rmi.activation \
+    java.rmi.dgc \
+    java.rmi.registry \
+    java.rmi.server \
+    javax.rmi.ssl \
+    javax.transaction \
+    javax.transaction.xa \
+    \
+    com.sun.net.httpserver \
+    com.sun.net.httpserver.spi
+
+profile.3.name = compact3
+profile.3.packages = \
+    java.lang.instrument \
+    java.lang.management \
+    java.security.acl \
+    java.util.prefs \
+    javax.management \
+    javax.management.loading \
+    javax.management.modelmbean \
+    javax.management.monitor \
+    javax.management.openmbean \
+    javax.management.relation \
+    javax.management.remote \
+    javax.management.remote.rmi \
+    javax.management.timer \
+    javax.naming \
+    javax.naming.directory \
+    javax.naming.event \
+    javax.naming.ldap \
+    javax.naming.spi \
+    javax.sql.rowset \
+    javax.sql.rowset.serial \
+    javax.sql.rowset.spi \
+    javax.security.auth.kerberos \
+    javax.security.sasl \
+    javax.script \
+    javax.smartcardio \
+    javax.xml.crypto \
+    javax.xml.crypto.dom \
+    javax.xml.crypto.dsig \
+    javax.xml.crypto.dsig.dom \
+    javax.xml.crypto.dsig.keyinfo \
+    javax.xml.crypto.dsig.spec \
+    javax.annotation.processing \
+    javax.lang.model \
+    javax.lang.model.element \
+    javax.lang.model.type \
+    javax.lang.model.util \
+    javax.tools \
+    javax.tools.annotation \
+    org.ietf.jgss \
+    \
+    com.sun.management \
+    com.sun.security.auth.callback \
+    com.sun.security.auth.module \
+    com.sun.security.jgss
+
+profile.4.name = Full JRE
+profile.4.packages = \
+    java.applet \
+    java.awt \
+    java.awt.color \
+    java.awt.datatransfer \
+    java.awt.dnd \
+    java.awt.dnd.peer \
+    java.awt.event \
+    java.awt.font \
+    java.awt.geom \
+    java.awt.im \
+    java.awt.im.spi \
+    java.awt.image \
+    java.awt.image.renderable \
+    java.awt.peer \
+    java.awt.print \
+    java.beans \
+    java.beans.beancontext \
+    javax.accessibility \
+    javax.imageio \
+    javax.imageio.event \
+    javax.imageio.metadata \
+    javax.imageio.plugins.bmp \
+    javax.imageio.plugins.jpeg \
+    javax.imageio.spi \
+    javax.imageio.stream \
+    javax.print \
+    javax.print.attribute \
+    javax.print.attribute.standard \
+    javax.print.event \
+    javax.sound.midi \
+    javax.sound.midi.spi \
+    javax.sound.sampled \
+    javax.sound.sampled.spi \
+    javax.swing \
+    javax.swing.border \
+    javax.swing.colorchooser \
+    javax.swing.event \
+    javax.swing.filechooser \
+    javax.swing.plaf \
+    javax.swing.plaf.basic \
+    javax.swing.plaf.metal \
+    javax.swing.plaf.multi \
+    javax.swing.plaf.nimbus \
+    javax.swing.plaf.synth \
+    javax.swing.table \
+    javax.swing.text \
+    javax.swing.text.html \
+    javax.swing.text.html.parser \
+    javax.swing.text.rtf \
+    javax.swing.tree \
+    javax.swing.undo \
+    javax.activation \
+    javax.jws \
+    javax.jws.soap \
+    javax.rmi \
+    javax.rmi.CORBA \
+    javax.xml.bind \
+    javax.xml.bind.annotation \
+    javax.xml.bind.annotation.adapters \
+    javax.xml.bind.attachment \
+    javax.xml.bind.helpers \
+    javax.xml.bind.util \
+    javax.xml.soap \
+    javax.xml.ws \
+    javax.xml.ws.handler \
+    javax.xml.ws.handler.soap \
+    javax.xml.ws.http \
+    javax.xml.ws.soap \
+    javax.xml.ws.spi \
+    javax.xml.ws.spi.http \
+    javax.xml.ws.wsaddressing \
+    javax.annotation \
+    org.omg.CORBA \
+    org.omg.CORBA.DynAnyPackage \
+    org.omg.CORBA.ORBPackage \
+    org.omg.CORBA.TypeCodePackage \
+    org.omg.CORBA.portable \
+    org.omg.CORBA_2_3 \
+    org.omg.CORBA_2_3.portable \
+    org.omg.CosNaming \
+    org.omg.CosNaming.NamingContextExtPackage \
+    org.omg.CosNaming.NamingContextPackage \
+    org.omg.Dynamic \
+    org.omg.DynamicAny \
+    org.omg.DynamicAny.DynAnyFactoryPackage \
+    org.omg.DynamicAny.DynAnyPackage \
+    org.omg.IOP \
+    org.omg.IOP.CodecFactoryPackage \
+    org.omg.IOP.CodecPackage \
+    org.omg.Messaging \
+    org.omg.PortableInterceptor \
+    org.omg.PortableInterceptor.ORBInitInfoPackage \
+    org.omg.PortableServer \
+    org.omg.PortableServer.CurrentPackage \
+    org.omg.PortableServer.POAManagerPackage \
+    org.omg.PortableServer.POAPackage \
+    org.omg.PortableServer.ServantLocatorPackage \
+    org.omg.PortableServer.portable \
+    org.omg.SendingContext \
+    org.omg.stub.java.rmi \
+    org.omg.stub.javax.management.remote.rmi
+
+# Remaining JDK supported API
+profile.5.name = JDK tools
+profile.5.packages = \
+    com.sun.jdi \
+    com.sun.jdi.connect \
+    com.sun.jdi.connect.spi \
+    com.sun.jdi.event \
+    com.sun.jdi.request \
+    com.sun.javadoc \
+    com.sun.tools.doclets \
+    com.sun.tools.doctree \
+    com.sun.source.tree \
+    com.sun.source.util \
+    com.sun.tools.attach \
+    com.sun.tools.attach.spi \
+    com.sun.tools.jconsole \
+    com.sun.tools.javac \
+    com.sun.tools.javah \
+    com.sun.tools.javap \
+    com.sun.tools.javadoc \
+    com.sun.servicetag
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/version.properties-template	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+jdk=$(JDK_VERSION)
+full=$(FULL_VERSION)
+release=$(RELEASE)
--- a/langtools/src/share/classes/javax/lang/model/element/Element.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/element/Element.java	Wed Jan 16 11:58:15 2013 -0800
@@ -179,6 +179,10 @@
      * instance initializer}, an empty name is returned.
      *
      * @return the simple name of this element
+     * @see PackageElement#getSimpleName
+     * @see ExecutableElement#getSimpleName
+     * @see TypeElement#getSimpleName
+     * @see VariableElement#getSimpleName
      */
     Name getSimpleName();
 
@@ -202,6 +206,11 @@
      * {@linkplain TypeParameterElement#getGenericElement the
      * generic element} of the type parameter is returned.
      *
+     * <li> If this is a {@linkplain
+     * VariableElement#getEnclosingElement method or constructor
+     * parameter}, {@linkplain ExecutableElement the executable
+     * element} which declares the parameter is returned.
+     *
      * </ul>
      *
      * @return the enclosing element, or {@code null} if there is none
--- a/langtools/src/share/classes/javax/lang/model/element/VariableElement.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/element/VariableElement.java	Wed Jan 16 11:58:15 2013 -0800
@@ -62,4 +62,29 @@
      * @jls 4.12.4 final Variables
      */
     Object getConstantValue();
+
+    /**
+     * Returns the simple name of this variable element.
+     *
+     * <p>For method and constructor parameters, the name of each
+     * parameter must be distinct from the names of all other
+     * parameters of the same executable.  If the original source
+     * names are not available, an implementation may synthesize names
+     * subject to the distinctness requirement above.
+     *
+     * @return the simple name of this variable element
+     */
+    @Override
+    Name getSimpleName();
+
+    /**
+     * Returns the enclosing element of this variable.
+     *
+     * The enclosing element of a method or constructor parameter is
+     * the executable declaring the parameter.
+     *
+     * @return the enclosing element of this variable
+     */
+    @Override
+    Element getEnclosingElement();
 }
--- a/langtools/src/share/classes/javax/lang/model/element/package-info.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/src/share/classes/javax/lang/model/element/package-info.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,9 +48,12 @@
  * {@linkplain java.lang.annotation.RetentionPolicy#SOURCE source}
  * {@linkplain java.lang.annotation.Retention retention} cannot be
  * recovered from class files and class files might not be able to
- * provide source position information.  The {@linkplain
- * javax.lang.model.element.Modifier modifiers} on an element may
- * differ in some cases including
+ * provide source position information.
+ *
+ * Names of parameters may not be recoverable from class files.
+ *
+ * The {@linkplain javax.lang.model.element.Modifier modifiers} on an
+ * element may differ in some cases including:
  *
  * <ul>
  * <li> {@code strictfp} on a class or interface
--- a/langtools/test/Makefile	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/Makefile	Wed Jan 16 11:58:15 2013 -0800
@@ -229,7 +229,7 @@
 all: $(JPRT_CLEAN) jtreg-tests jck-compiler-tests jck-runtime-tests $(JPRT_ARCHIVE_BUNDLE) all-summary
 	@echo "Testing completed successfully"
 
-jtreg apt javac javadoc javah javap: $(JPRT_CLEAN) jtreg-tests $(JPRT_ARCHIVE_BUNDLE) jtreg-summary
+jtreg apt javac javadoc javah javap jdeps: $(JPRT_CLEAN) jtreg-tests $(JPRT_ARCHIVE_BUNDLE) jtreg-summary
 	@echo "Testing completed successfully"
 
 jck-compiler: $(JPRT_CLEAN) jck-compiler-tests $(JPRT_ARCHIVE_BUNDLE) jck-compiler-summary
@@ -246,6 +246,7 @@
 javadoc:	JTREG_TESTDIRS = tools/javadoc com/sun/javadoc
 javah:		JTREG_TESTDIRS = tools/javah
 javap:		JTREG_TESTDIRS = tools/javap
+jdeps:		JTREG_TESTDIRS = tools/jdeps
 
 # Run jtreg tests
 #
@@ -426,7 +427,7 @@
 
 # Phony targets (e.g. these are not filenames)
 .PHONY: all clean \
-	jtreg javac javadoc javah javap jtreg-tests jtreg-summary check-jtreg \
+	jtreg javac javadoc javah javap jdeps jtreg-tests jtreg-summary check-jtreg \
 	jck-compiler jck-compiler-tests jck-compiler-summary \
 	jck-runtime jck-runtime-tests jck-runtime-summary check-jck
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testAbstractMethod/TestAbstractMethod.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug      8004891
+ * @summary  Make sure that the abstract method is identified correctly
+ *           if the abstract modifier is present explicitly or implicitly.
+ * @author   bpatel
+ * @library  ../lib/
+ * @build    JavadocTester TestAbstractMethod
+ * @run main TestAbstractMethod
+ */
+
+public class TestAbstractMethod extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8004891";
+
+    //Javadoc arguments.
+    private static final String[] ARGS = new String[] {
+        "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg"
+    };
+
+    //Input for string search tests.
+    private static final String[][] TEST = {
+        {BUG_ID + FS + "pkg" + FS + "A.html",
+            "<td class=\"colFirst\"><code>default void</code></td>"},
+        {BUG_ID + FS + "pkg" + FS + "A.html",
+            "<caption><span id=\"t0\" class=\"activeTableTab\"><span>" +
+            "All Methods</span><span class=\"tabEnd\">&nbsp;</span></span>" +
+            "<span id=\"t2\" class=\"tableTab\"><span>" +
+            "<a href=\"javascript:show(2);\">Instance Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" " +
+            "class=\"tableTab\"><span><a href=\"javascript:show(4);\">" +
+            "Abstract Methods</a></span><span class=\"tabEnd\">&nbsp;</span>" +
+            "</span><span id=\"t5\" class=\"tableTab\"><span>" +
+            "<a href=\"javascript:show(16);\">Default Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span></span></caption>"},
+        {BUG_ID + FS + "pkg" + FS + "B.html",
+            "<caption><span id=\"t0\" class=\"activeTableTab\"><span>" +
+            "All Methods</span><span class=\"tabEnd\">&nbsp;</span></span>" +
+            "<span id=\"t2\" class=\"tableTab\"><span>" +
+            "<a href=\"javascript:show(2);\">Instance Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span></span><span id=\"t3\" " +
+            "class=\"tableTab\"><span><a href=\"javascript:show(4);\">Abstract " +
+            "Methods</a></span><span class=\"tabEnd\">&nbsp;</span></span>" +
+            "<span id=\"t4\" class=\"tableTab\"><span>" +
+            "<a href=\"javascript:show(8);\">Concrete Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span></span></caption>"},
+        {BUG_ID + FS + "pkg" + FS + "B.html",
+            "<td class=\"colFirst\"><code>abstract void</code></td>"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<caption><span id=\"t0\" class=\"activeTableTab\"><span>" +
+            "All Methods</span><span class=\"tabEnd\">&nbsp;</span></span>" +
+            "<span id=\"t2\" class=\"tableTab\"><span>" +
+            "<a href=\"javascript:show(2);\">Instance Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span></span>" +
+            "<span id=\"t5\" class=\"tableTab\"><span>" +
+            "<a href=\"javascript:show(16);\">Default Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span></span></caption>"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<td class=\"colFirst\"><code>default void</code></td>"}
+    };
+    private static final String[][] NEGATED_TEST = {
+        {BUG_ID + FS + "pkg" + FS + "A.html",
+            "<td class=\"colFirst\"><code>abstract void</code></td>"},
+        {BUG_ID + FS + "pkg" + FS + "B.html",
+            "<span><a href=\"javascript:show(16);\">Default Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span>"},
+        {BUG_ID + FS + "pkg" + FS + "B.html",
+            "<td class=\"colFirst\"><code>default void</code></td>"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<span><a href=\"javascript:show(4);\">Abstract Methods</a></span>" +
+            "<span class=\"tabEnd\">&nbsp;</span>"}
+    };
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestAbstractMethod tester = new TestAbstractMethod();
+        run(tester, ARGS, TEST, NEGATED_TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testAbstractMethod/pkg/A.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+public interface A {
+
+    public void method1();
+
+    public default void defaultMethod() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testAbstractMethod/pkg/B.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+public abstract class B {
+
+    public abstract void method1();
+
+    public void method2() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testAbstractMethod/pkg/C.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+public interface C {
+
+    public default void onlyMethod() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/TestRepeatedAnnotations.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug      8005092
+ * @summary  Test repeated annotations output.
+ * @author   bpatel
+ * @library  ../lib/
+ * @build    JavadocTester TestRepeatedAnnotations
+ * @run main TestRepeatedAnnotations
+ */
+
+public class TestRepeatedAnnotations extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8005092";
+
+    //Javadoc arguments.
+    private static final String[] ARGS = new String[] {
+        "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg", "pkg1"
+    };
+
+    //Input for string search tests.
+    private static final String[][] TEST = {
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a> " +
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a>"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/ContaineeRegDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeRegDoc</a> " +
+            "<a href=\"../pkg/ContaineeRegDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeRegDoc</a>"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/RegContainerDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContainerDoc</a>" +
+            "(<a href=\"../pkg/RegContainerDoc.html#value()\">value</a>={" +
+            "<a href=\"../pkg/RegContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContaineeNotDoc</a>," +
+            "<a href=\"../pkg/RegContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContaineeNotDoc</a>})"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a> " +
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a> " +
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a>"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/ContainerSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContainerSynthDoc</a>(" +
+            "<a href=\"../pkg/ContainerSynthDoc.html#value()\">value</a>=" +
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a>)"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a> " +
+            "<a href=\"../pkg/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg\">@ContaineeSynthDoc</a>"},
+
+        {BUG_ID + FS + "pkg" + FS + "D.html",
+            "<a href=\"../pkg/RegDoc.html\" title=\"annotation in pkg\">@RegDoc</a>" +
+            "(<a href=\"../pkg/RegDoc.html#x()\">x</a>=1)"},
+        {BUG_ID + FS + "pkg" + FS + "D.html",
+            "<a href=\"../pkg/RegArryDoc.html\" title=\"annotation in pkg\">@RegArryDoc</a>" +
+            "(<a href=\"../pkg/RegArryDoc.html#y()\">y</a>=1)"},
+        {BUG_ID + FS + "pkg" + FS + "D.html",
+            "<a href=\"../pkg/RegArryDoc.html\" title=\"annotation in pkg\">@RegArryDoc</a>" +
+            "(<a href=\"../pkg/RegArryDoc.html#y()\">y</a>={1,2})"},
+        {BUG_ID + FS + "pkg" + FS + "D.html",
+            "<a href=\"../pkg/NonSynthDocContainer.html\" " +
+            "title=\"annotation in pkg\">@NonSynthDocContainer</a>" +
+            "(<a href=\"../pkg/NonSynthDocContainer.html#value()\">value</a>=" +
+            "<a href=\"../pkg/RegArryDoc.html\" title=\"annotation in pkg\">@RegArryDoc</a>)"},
+
+        {BUG_ID + FS + "pkg1" + FS + "C.html",
+            "<a href=\"../pkg1/RegContainerValDoc.html\" " +
+            "title=\"annotation in pkg1\">@RegContainerValDoc</a>" +
+            "(<a href=\"../pkg1/RegContainerValDoc.html#value()\">value</a>={" +
+            "<a href=\"../pkg1/RegContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@RegContaineeNotDoc</a>," +
+            "<a href=\"../pkg1/RegContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@RegContaineeNotDoc</a>}," +
+            "<a href=\"../pkg1/RegContainerValDoc.html#y()\">y</a>=3)"},
+        {BUG_ID + FS + "pkg1" + FS + "C.html",
+            "<a href=\"../pkg1/ContainerValDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContainerValDoc</a>" +
+            "(<a href=\"../pkg1/ContainerValDoc.html#value()\">value</a>={" +
+            "<a href=\"../pkg1/ContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContaineeNotDoc</a>," +
+            "<a href=\"../pkg1/ContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContaineeNotDoc</a>}," +
+            "<a href=\"../pkg1/ContainerValDoc.html#x()\">x</a>=1)"}
+    };
+
+    private static final String[][] NEGATED_TEST = {
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/RegContaineeDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContaineeDoc</a> " +
+            "<a href=\"../pkg/RegContaineeDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContaineeDoc</a>"},
+        {BUG_ID + FS + "pkg" + FS + "C.html",
+            "<a href=\"../pkg/RegContainerNotDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContainerNotDoc</a>" +
+            "(<a href=\"../pkg/RegContainerNotDoc.html#value()\">value</a>={" +
+            "<a href=\"../pkg/RegContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContaineeNotDoc</a>," +
+            "<a href=\"../pkg/RegContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg\">@RegContaineeNotDoc</a>})"},
+
+        {BUG_ID + FS + "pkg1" + FS + "C.html",
+            "<a href=\"../pkg1/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContaineeSynthDoc</a> " +
+            "<a href=\"../pkg1/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContaineeSynthDoc</a>"},
+        {BUG_ID + FS + "pkg1" + FS + "C.html",
+            "<a href=\"../pkg1/RegContainerValNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@RegContainerValNotDoc</a>" +
+            "(<a href=\"../pkg1/RegContainerValNotDoc.html#value()\">value</a>={" +
+            "<a href=\"../pkg1/RegContaineeDoc.html\" " +
+            "title=\"annotation in pkg1\">@RegContaineeDoc</a>," +
+            "<a href=\"../pkg1/RegContaineeDoc.html\" " +
+            "title=\"annotation in pkg1\">@RegContaineeDoc</a>}," +
+            "<a href=\"../pkg1/RegContainerValNotDoc.html#y()\">y</a>=4)"},
+        {BUG_ID + FS + "pkg1" + FS + "C.html",
+            "<a href=\"../pkg1/ContainerValNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContainerValNotDoc</a>" +
+            "(<a href=\"../pkg1/ContainerValNotDoc.html#value()\">value</a>={" +
+            "<a href=\"../pkg1/ContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContaineeNotDoc</a>," +
+            "<a href=\"../pkg1/ContaineeNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContaineeNotDoc</a>}," +
+            "<a href=\"../pkg1/ContainerValNotDoc.html#x()\">x</a>=2)"},
+        {BUG_ID + FS + "pkg1" + FS + "C.html",
+            "<a href=\"../pkg1/ContainerSynthNotDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContainerSynthNotDoc</a>(" +
+            "<a href=\"../pkg1/ContainerSynthNotDoc.html#value()\">value</a>=" +
+            "<a href=\"../pkg1/ContaineeSynthDoc.html\" " +
+            "title=\"annotation in pkg1\">@ContaineeSynthDoc</a>)"}
+    };
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestRepeatedAnnotations tester = new TestRepeatedAnnotations();
+        run(tester, ARGS, TEST, NEGATED_TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/C.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+@ContainerSynthDoc(value={@ContaineeSynthDoc,@ContaineeSynthDoc})
+@ContainerRegDoc(value={@ContaineeRegDoc,@ContaineeRegDoc})
+@RegContainerDoc(value={@RegContaineeNotDoc,@RegContaineeNotDoc})
+@ContainerRegNotDoc(value={@RegContaineeDoc,@RegContaineeDoc})
+@RegContainerNotDoc(value={@RegContaineeNotDoc,@RegContaineeNotDoc})
+@ContaineeSynthDoc @ContaineeSynthDoc @ContaineeSynthDoc
+public class C {
+
+    @ContainerSynthDoc(value={@ContaineeSynthDoc})
+    public void test1() {}
+
+    @ContaineeSynthDoc @ContaineeSynthDoc
+    public void test2() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeRegDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation contained by ContainerRegDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface ContaineeRegDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContaineeSynthDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented synthesized annotation contained by ContainerSynthDoc.
+ * It will be used to annotate Class C and a method in the class using a synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+@ContainedBy(ContainerSynthDoc.class)
+public @interface ContaineeSynthDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerRegDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation container for ContaineeRegDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface ContainerRegDoc {
+
+    ContaineeRegDoc[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerRegNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented annotation container for RegContaineeDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface ContainerRegNotDoc {
+
+    RegContaineeDoc[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/ContainerSynthDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented synthesized annotation container for ContaineeSynthDoc.
+ * It will be used to annotate Class C and a method in the class using a synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+@ContainerFor(ContaineeSynthDoc.class)
+public @interface ContainerSynthDoc {
+
+    ContaineeSynthDoc[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/D.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+@RegDoc(x=1)
+public class D {
+
+    @RegArryDoc(y={1})
+    public void test1() {}
+
+    @RegArryDoc(y={1,2})
+    public void test2() {}
+
+    @NonSynthDocContainer(value={@RegArryDoc})
+    public void test3() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/NonSynthDocContainer.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation.
+ * It will be used to annotate methods in class D.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface NonSynthDocContainer {
+
+    RegArryDoc[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/RegArryDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation.
+ * It will be used to annotate methods in Class D.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface RegArryDoc {
+
+    int[] y();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/RegContaineeDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation contained by ContainerRegNotDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface RegContaineeDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/RegContaineeNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented annotation contained by RegContainerNotDoc
+ * and RegContainerDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface RegContaineeNotDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/RegContainerDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation container for RegContainerDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface RegContainerDoc {
+
+    RegContaineeNotDoc[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/RegContainerNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented annotation container for RegContaineeNotDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface RegContainerNotDoc {
+
+    RegContaineeNotDoc[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg/RegDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation.
+ * It will be used to annotate Class D.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface RegDoc {
+
+    int x();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/C.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+@ContainerSynthNotDoc(value={@ContaineeSynthDoc,@ContaineeSynthDoc})
+@RegContainerValDoc(value={@RegContaineeNotDoc,@RegContaineeNotDoc},y=3)
+@ContainerValDoc(value={@ContaineeNotDoc,@ContaineeNotDoc},x=1)
+@RegContainerValNotDoc(value={@RegContaineeDoc,@RegContaineeDoc},y=4)
+@ContainerValNotDoc(value={@ContaineeNotDoc,@ContaineeNotDoc},x=2)
+public class C {
+
+    @ContainerSynthNotDoc(value={@ContaineeSynthDoc})
+    public void test1() {}
+
+    @ContaineeSynthDoc @ContaineeSynthDoc
+    public void test2() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented annotation contained by ContainerValNotDoc
+ * and ContainerValDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface ContaineeNotDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContaineeSynthDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented synthesized annotation contained by ContainerSynthNotDoc.
+ * It will be used to annotate Class C and methods in the class using a synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+@ContainedBy(ContainerSynthNotDoc.class)
+public @interface ContaineeSynthDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerSynthNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented synthesized annotation container for ContaineeSynthDoc.
+ * It will be used to annotate Class C and methods in the class using a synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@ContainerFor(ContaineeSynthDoc.class)
+public @interface ContainerSynthNotDoc {
+
+    ContaineeSynthDoc[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerValDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation container for ContaineeNotDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface ContainerValDoc {
+
+    ContaineeNotDoc[] value();
+
+    int x();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/ContainerValNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented annotation container for ContaineeNotDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface ContainerValNotDoc {
+
+    ContaineeNotDoc[] value();
+
+    int x();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/RegContaineeDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation contained by RegContainerValNotDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface RegContaineeDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/RegContaineeNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented annotation contained by RegContainerValDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface RegContaineeNotDoc {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/RegContainerValDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a documented annotation container for RegContaineeNotDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+@Documented
+public @interface RegContainerValDoc {
+
+    RegContaineeNotDoc[] value();
+
+    int y();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testRepeatedAnnotations/pkg1/RegContainerValNotDoc.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg1;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation is a non-documented annotation container for RegContaineeDoc.
+ * It will be used to annotate Class C using a non-synthesized form.
+ *
+ * @author Bhavesh Patel
+ */
+public @interface RegContainerValNotDoc {
+
+    RegContaineeDoc[] value();
+
+    int y();
+}
--- a/langtools/test/tools/doclint/DocLintTester.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/doclint/DocLintTester.java	Wed Jan 16 11:58:15 2013 -0800
@@ -107,7 +107,7 @@
 
     private static final Pattern dirFileLine = Pattern.compile(
             "(?m)"                          // multi-line mode
-            + "^([^: ]+?)"                  // directory part of file name
+            + "^(.*?)"                      // directory part of file name
             + "([A-Za-z0-9.]+:[0-9]+:)");   // file name and line number
 
     String removeFileNames(String s) {
--- a/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/Diagnostics/6769027/T6769027.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,14 +26,19 @@
  * @bug     6769027
  * @summary Source line should be displayed immediately after the first diagnostic line
  * @author  Maurizio Cimadamore
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
  * @run main/othervm T6769027
  */
+
 import java.net.URI;
 import java.util.regex.Matcher;
 import javax.tools.*;
 import com.sun.tools.javac.util.*;
 
-public class T6769027 {
+public class T6769027
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum OutputKind {
         RAW("rawDiagnostics","rawDiagnostics"),
@@ -314,7 +319,7 @@
 
         @Override
         protected java.io.PrintWriter getWriterForDiagnosticType(JCDiagnostic.DiagnosticType dt) {
-            return new java.io.PrintWriter(System.out);
+            return outWriter;
         }
 
         @Override
@@ -323,13 +328,42 @@
         }
     }
 
-    int nerrors = 0;
+    OutputKind outputKind;
+    ErrorKind errorKind;
+    MultilineKind multiKind;
+    MultilinePolicy multiPolicy;
+    PositionKind posKind;
+    XDiagsSource xdiagsSource;
+    XDiagsCompact xdiagsCompact;
+    CaretKind caretKind;
+    SourceLineKind sourceLineKind;
+    IndentKind summaryIndent;
+    IndentKind detailsIndent;
+    IndentKind sourceIndent;
+    IndentKind subdiagsIndent;
 
-    void exec(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
+    T6769027(OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
             MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
             XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
             IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
             IndentKind subdiagsIndent) {
+        this.outputKind = outputKind;
+        this.errorKind = errorKind;
+        this.multiKind = multiKind;
+        this.multiPolicy = multiPolicy;
+        this.posKind = posKind;
+        this.xdiagsSource = xdiagsSource;
+        this.xdiagsCompact = xdiagsCompact;
+        this.caretKind = caretKind;
+        this.sourceLineKind = sourceLineKind;
+        this.summaryIndent = summaryIndent;
+        this.detailsIndent = detailsIndent;
+        this.sourceIndent = sourceIndent;
+        this.subdiagsIndent = subdiagsIndent;
+    }
+
+    @Override
+    public void run() {
         Context ctx = new Context();
         Options options = Options.instance(ctx);
         outputKind.init(options);
@@ -362,23 +396,10 @@
             d = new JCDiagnostic.MultilineDiagnostic(d, subdiags);
         }
         String diag = log.getDiagnosticFormatter().format(d, messages.getCurrentLocale());
-        checkOutput(diag,
-                outputKind,
-                errorKind,
-                multiKind,
-                multiPolicy,
-                posKind,
-                xdiagsSource,
-                xdiagsCompact,
-                caretKind,
-                sourceLineKind,
-                summaryIndent,
-                detailsIndent,
-                sourceIndent,
-                subdiagsIndent);
+        checkOutput(diag);
     }
 
-    void test() {
+    public static void main(String[] args) throws Exception {
         for (OutputKind outputKind : OutputKind.values()) {
             for (ErrorKind errKind : ErrorKind.values()) {
                 for (MultilineKind multiKind : MultilineKind.values()) {
@@ -392,7 +413,7 @@
                                                 for (IndentKind detailsIndent : IndentKind.values()) {
                                                     for (IndentKind sourceIndent : IndentKind.values()) {
                                                         for (IndentKind subdiagsIndent : IndentKind.values()) {
-                                                            exec(outputKind,
+                                                            pool.execute(new T6769027(outputKind,
                                                                 errKind,
                                                                 multiKind,
                                                                 multiPolicy,
@@ -404,7 +425,7 @@
                                                                 summaryIndent,
                                                                 detailsIndent,
                                                                 sourceIndent,
-                                                                subdiagsIndent);
+                                                                subdiagsIndent));
                                                         }
                                                     }
                                                 }
@@ -418,15 +439,11 @@
                 }
             }
         }
-        if (nerrors != 0)
-            throw new AssertionError(nerrors + " errors found");
+
+        checkAfterExec(false);
     }
 
-    void printInfo(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
-            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
-            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
-            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
-            IndentKind subdiagsIndent, String errorLine) {
+    void printInfo(String msg, String errorLine) {
         String sep = "*********************************************************";
         String desc = "raw=" + outputKind + " pos=" + posKind + " key=" + errorKind.key() +
                 " multiline=" + multiKind +" multiPolicy=" + multiPolicy.value +
@@ -434,18 +451,14 @@
                 " caret=" + caretKind + " sourcePosition=" + sourceLineKind +
                 " summaryIndent=" + summaryIndent + " detailsIndent=" + detailsIndent +
                 " sourceIndent=" + sourceIndent + " subdiagsIndent=" + subdiagsIndent;
-        System.out.println(sep);
-        System.out.println(desc);
-        System.out.println(sep);
-        System.out.println(msg);
-        System.out.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
+        errWriter.println(sep);
+        errWriter.println(desc);
+        errWriter.println(sep);
+        errWriter.println(msg);
+        errWriter.println("Diagnostic formatting problem - expected diagnostic...\n" + errorLine);
     }
 
-    void checkOutput(String msg, OutputKind outputKind, ErrorKind errorKind, MultilineKind multiKind,
-            MultilinePolicy multiPolicy, PositionKind posKind, XDiagsSource xdiagsSource,
-            XDiagsCompact xdiagsCompact, CaretKind caretKind, SourceLineKind sourceLineKind,
-            IndentKind summaryIndent, IndentKind detailsIndent, IndentKind sourceIndent,
-            IndentKind subdiagsIndent) {
+    void checkOutput(String msg) {
         boolean shouldPrintSource = posKind == PositionKind.POS &&
                 xdiagsSource != XDiagsSource.NO_SOURCE &&
                 (xdiagsSource == XDiagsSource.SOURCE ||
@@ -453,7 +466,8 @@
         String errorLine = posKind.getOutput(outputKind) +
                 errorKind.getOutput(outputKind, summaryIndent, detailsIndent);
         if (xdiagsCompact != XDiagsCompact.COMPACT)
-            errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy, summaryIndent, detailsIndent, subdiagsIndent);
+            errorLine += multiKind.getOutput(outputKind, errorKind, multiPolicy,
+                    summaryIndent, detailsIndent, subdiagsIndent);
         String[] lines = errorLine.split("\n");
         if (xdiagsCompact == XDiagsCompact.COMPACT) {
             errorLine = lines[0];
@@ -474,26 +488,9 @@
         }
 
         if (!msg.equals(errorLine)) {
-            printInfo(msg,
-                    outputKind,
-                    errorKind,
-                    multiKind,
-                    multiPolicy,
-                    posKind,
-                    xdiagsSource,
-                    xdiagsCompact,
-                    caretKind,
-                    sourceLineKind,
-                    summaryIndent,
-                    detailsIndent,
-                    sourceIndent,
-                    subdiagsIndent,
-                    errorLine);
-            nerrors++;
+            printInfo(msg, errorLine);
+            errCount.incrementAndGet();
         }
     }
 
-    public static void main(String... args) throws Exception {
-        new T6769027().test();
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/MethodParameters.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004727
+ * @summary javac should generate method parameters correctly.
+ */
+// key: opt.arg.parameters
+import com.sun.tools.classfile.*;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import java.io.*;
+import javax.lang.model.element.*;
+import java.util.*;
+
+public class MethodParameters {
+
+    static final String Foo_name = "Foo";
+    static final String Foo_contents =
+        "public class Foo {\n" +
+        "  Foo() {}\n" +
+        "  void foo0() {}\n" +
+        "  void foo2(int j, int k) {}\n" +
+        "}";
+    static final String Bar_name = "Bar";
+    static final String Bar_contents =
+        "public class Bar {\n" +
+        "  Bar(int i) {}" +
+        "  Foo foo() { return new Foo(); }\n" +
+        "}";
+    static final String Baz_name = "Baz";
+    static final String Baz_contents =
+        "public class Baz {\n" +
+        "  int baz;" +
+        "  Baz(int i) {}" +
+        "}";
+    static final String Qux_name = "Qux";
+    static final String Qux_contents =
+        "public class Qux extends Baz {\n" +
+        "  Qux(int i) { super(i); }" +
+        "}";
+    static final File classesdir = new File("methodparameters");
+
+    public static void main(String... args) throws Exception {
+        new MethodParameters().run();
+    }
+
+    void run() throws Exception {
+        classesdir.mkdir();
+        final File Foo_java =
+            writeFile(classesdir, Foo_name + ".java", Foo_contents);
+        final File Bar_java =
+            writeFile(classesdir, Bar_name + ".java", Bar_contents);
+        final File Baz_java =
+            writeFile(classesdir, Baz_name + ".java", Baz_contents);
+        System.err.println("Test compile with -parameter");
+        compile("-parameters", "-d", classesdir.getPath(), Foo_java.getPath());
+        // First test: make sure javac doesn't choke to death on
+        // MethodParameter attributes
+        System.err.println("Test compile with classfile containing MethodParameter attributes");
+        compile("-parameters", "-d", classesdir.getPath(),
+                "-cp", classesdir.getPath(), Bar_java.getPath());
+        System.err.println("Examine class foo");
+        checkFoo();
+        checkBar();
+        System.err.println("Test debug information conflict");
+        compile("-g", "-parameters", "-d", classesdir.getPath(),
+                "-cp", classesdir.getPath(), Baz_java.getPath());
+        System.err.println("Introducing debug information conflict");
+        Baz_java.delete();
+        modifyBaz(false);
+        System.err.println("Checking language model");
+        inspectBaz();
+        System.err.println("Permuting attributes");
+        modifyBaz(true);
+        System.err.println("Checking language model");
+        inspectBaz();
+
+        if(0 != errors)
+            throw new Exception("MethodParameters test failed with " +
+                                errors + " errors");
+    }
+
+    void inspectBaz() throws Exception {
+        final File Qux_java =
+            writeFile(classesdir, Qux_name + ".java", Qux_contents);
+        final String[] args = { "-XDsave-parameter-names", "-d",
+                                classesdir.getPath(),
+                                "-cp", classesdir.getPath(),
+                                Qux_java.getPath() };
+        final StringWriter sw = new StringWriter();
+        final PrintWriter pw = new PrintWriter(sw);
+
+        // We need to be able to crack open javac and look at its data
+        // structures.  We'll rig up a compiler instance, but keep its
+        // Context, thus allowing us to get at the ClassReader.
+        Context context = new Context();
+        Main comp =  new Main("javac", pw);
+        JavacFileManager.preRegister(context);
+
+        // Compile Qux, which uses Baz.
+        comp.compile(args, context);
+        pw.close();
+        final String out = sw.toString();
+        if (out.length() > 0)
+            System.err.println(out);
+
+        // Now get the class reader, construct a name for Baz, and load it.
+        com.sun.tools.javac.jvm.ClassReader cr =
+            com.sun.tools.javac.jvm.ClassReader.instance(context);
+        Name name = Names.instance(context).fromString(Baz_name);
+
+        // Now walk down the language model and check the name of the
+        // parameter.
+        final Element baz = cr.loadClass(name);
+        for (Element e : baz.getEnclosedElements()) {
+            if (e instanceof ExecutableElement) {
+                final ExecutableElement ee = (ExecutableElement) e;
+                final List<? extends VariableElement> params =
+                    ee.getParameters();
+                if (1 != params.size())
+                    throw new Exception("Classfile Baz badly formed: wrong number of methods");
+                final VariableElement param = params.get(0);
+                if (!param.getSimpleName().contentEquals("baz")) {
+                    errors++;
+                    System.err.println("javac did not correctly resolve the metadata conflict, parameter's name reads as " + param.getSimpleName());
+                } else
+                    System.err.println("javac did correctly resolve the metadata conflict");
+            }
+        }
+    }
+
+    void modifyBaz(boolean flip) throws Exception {
+        final File Baz_class = new File(classesdir, Baz_name + ".class");
+        final ClassFile baz = ClassFile.read(Baz_class);
+        final int ind = baz.constant_pool.getUTF8Index("baz");
+        MethodParameters_attribute mpattr = null;
+        int mpind = 0;
+        Code_attribute cattr = null;
+        int cind = 0;
+
+        // Find the indexes of the MethodParameters and the Code attributes
+        if (baz.methods.length != 1)
+            throw new Exception("Classfile Baz badly formed: wrong number of methods");
+        if (!baz.methods[0].getName(baz.constant_pool).equals("<init>"))
+            throw new Exception("Classfile Baz badly formed: method has name " +
+                                baz.methods[0].getName(baz.constant_pool));
+        for (int i = 0; i < baz.methods[0].attributes.attrs.length; i++) {
+            if (baz.methods[0].attributes.attrs[i] instanceof
+                MethodParameters_attribute) {
+                mpattr = (MethodParameters_attribute)
+                    baz.methods[0].attributes.attrs[i];
+                mpind = i;
+            } else if (baz.methods[0].attributes.attrs[i] instanceof
+                       Code_attribute) {
+                cattr = (Code_attribute) baz.methods[0].attributes.attrs[i];
+                cind = i;
+            }
+        }
+        if (null == mpattr)
+            throw new Exception("Classfile Baz badly formed: no method parameters info");
+        if (null == cattr)
+            throw new Exception("Classfile Baz badly formed: no local variable table");
+
+        int flags = mpattr.method_parameter_table[0].flags;
+
+        // Alter the MethodParameters attribute, changing the name of
+        // the parameter from i to baz.  This requires Black Magic...
+        //
+        // The (well-designed) classfile library (correctly) does not
+        // allow us to mess around with the attribute data structures,
+        // or arbitrarily generate new ones.
+        //
+        // Instead, we install a new subclass of Attribute that
+        // hijacks the Visitor pattern and outputs the sequence of
+        // bytes that we want.  This only works in this particular
+        // instance, because we know we'll only every see one kind of
+        // visitor.
+        //
+        // If anyone ever changes the makeup of the Baz class, or
+        // tries to install some kind of visitor that gets run prior
+        // to serialization, this will break.
+        baz.methods[0].attributes.attrs[mpind] =
+            new Attribute(mpattr.attribute_name_index,
+                          mpattr.attribute_length) {
+                public <R, D> R accept(Visitor<R, D> visitor, D data) {
+                    if (data instanceof ByteArrayOutputStream) {
+                        ByteArrayOutputStream out =
+                            (ByteArrayOutputStream) data;
+                        out.write(1);
+                        out.write((ind >> 8) & 0xff);
+                        out.write(ind & 0xff);
+                        out.write((flags >> 24) & 0xff);
+                        out.write((flags >> 16) & 0xff);
+                        out.write((flags >> 8) & 0xff);
+                        out.write(flags & 0xff);
+                    } else
+                        throw new RuntimeException("Output stream is of type " + data.getClass() + ", which is not handled by this test.  Update the test and it should work.");
+                    return null;
+                }
+            };
+
+        // Flip the code and method attributes.  This is for checking
+        // that order doesn't matter.
+        if (flip) {
+            baz.methods[0].attributes.attrs[mpind] = cattr;
+            baz.methods[0].attributes.attrs[cind] = mpattr;
+        }
+
+        new ClassWriter().write(baz, Baz_class);
+    }
+
+    // Run a bunch of structural tests on foo to make sure it looks right.
+    void checkFoo() throws Exception {
+        final File Foo_class = new File(classesdir, Foo_name + ".class");
+        final ClassFile foo = ClassFile.read(Foo_class);
+        for (int i = 0; i < foo.methods.length; i++) {
+            System.err.println("Examine method Foo." + foo.methods[i].getName(foo.constant_pool));
+            if (foo.methods[i].getName(foo.constant_pool).equals("foo2")) {
+                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
+                    if (foo.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute) {
+                        MethodParameters_attribute mp =
+                            (MethodParameters_attribute)
+                            foo.methods[i].attributes.attrs[j];
+                        System.err.println("Foo.foo2 should have 2 parameters: j and k");
+                        if (2 != mp.method_parameter_table_length)
+                            error("expected 2 method parameter entries in foo2, got " +
+                                  mp.method_parameter_table_length);
+                        else if (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("j"))
+                            error("expected first parameter to foo2 to be \"j\", got \"" +
+                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
+                                  "\" instead");
+                        else if  (!foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index).equals("k"))
+                            error("expected first parameter to foo2 to be \"k\", got \"" +
+                                  foo.constant_pool.getUTF8Value(mp.method_parameter_table[1].name_index) +
+                                  "\" instead");
+                    }
+            }
+            else if (foo.methods[i].getName(foo.constant_pool).equals("<init>")) {
+                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++) {
+                    if (foo.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute)
+                        error("Zero-argument constructor shouldn't have MethodParameters");
+                }
+            }
+            else if (foo.methods[i].getName(foo.constant_pool).equals("foo0")) {
+                for (int j = 0; j < foo.methods[i].attributes.attrs.length; j++)
+                    if (foo.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute)
+                        error("Zero-argument method shouldn't have MethodParameters");
+            }
+            else
+                error("Unknown method " + foo.methods[i].getName(foo.constant_pool) + " showed up in class Foo");
+        }
+    }
+
+    // Run a bunch of structural tests on Bar to make sure it looks right.
+    void checkBar() throws Exception {
+        final File Bar_class = new File(classesdir, Bar_name + ".class");
+        final ClassFile bar = ClassFile.read(Bar_class);
+        for (int i = 0; i < bar.methods.length; i++) {
+            System.err.println("Examine method Bar." + bar.methods[i].getName(bar.constant_pool));
+            if (bar.methods[i].getName(bar.constant_pool).equals("<init>")) {
+                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++)
+                    if (bar.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute) {
+                        MethodParameters_attribute mp =
+                            (MethodParameters_attribute)
+                            bar.methods[i].attributes.attrs[j];
+                        System.err.println("Bar constructor should have 1 parameter: i");
+                        if (1 != mp.method_parameter_table_length)
+                            error("expected 1 method parameter entries in constructor, got " +
+                                  mp.method_parameter_table_length);
+                        else if (!bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index).equals("i"))
+                            error("expected first parameter to foo2 to be \"i\", got \"" +
+                                  bar.constant_pool.getUTF8Value(mp.method_parameter_table[0].name_index) +
+                                  "\" instead");
+                    }
+            }
+            else if (bar.methods[i].getName(bar.constant_pool).equals("foo")) {
+                for (int j = 0; j < bar.methods[i].attributes.attrs.length; j++) {
+                    if (bar.methods[i].attributes.attrs[j] instanceof
+                        MethodParameters_attribute)
+                        error("Zero-argument constructor shouldn't have MethodParameters");
+                }
+            }
+        }
+    }
+
+    String compile(String... args) throws Exception {
+        System.err.println("compile: " + Arrays.asList(args));
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(args, pw);
+        pw.close();
+        String out = sw.toString();
+        if (out.length() > 0)
+            System.err.println(out);
+        if (rc != 0)
+            error("compilation failed, rc=" + rc);
+        return out;
+    }
+
+    File writeFile(File dir, String path, String body) throws IOException {
+        File f = new File(dir, path);
+        f.getParentFile().mkdirs();
+        FileWriter out = new FileWriter(f);
+        out.write(body);
+        out.close();
+        return f;
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+}
--- a/langtools/test/tools/javac/T7093325.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/T7093325.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,35 +25,29 @@
  * @test
  * @bug 7093325
  * @summary Redundant entry in bytecode exception table
+ * @library lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main T7093325
  */
 
+import java.io.File;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
 import com.sun.source.util.JavacTask;
 import com.sun.tools.classfile.Attribute;
 import com.sun.tools.classfile.ClassFile;
 import com.sun.tools.classfile.Code_attribute;
 import com.sun.tools.classfile.ConstantPool.*;
 import com.sun.tools.classfile.Method;
-import com.sun.tools.javac.api.JavacTool;
 
-import java.io.File;
-import java.net.URI;
-import java.util.Arrays;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
-
-
-public class T7093325 {
-
-    /** global decls ***/
-
-    // Create a single file manager and reuse it for each compile to save time.
-    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
-
-    //statistics
-    static int checkCount = 0;
+public class T7093325
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum StatementKind {
         THROW("throw new RuntimeException();", false, false),
@@ -89,7 +83,8 @@
             if (this.ordinal() == 0) {
                 return catchStr;
             } else {
-                return CatchArity.values()[this.ordinal() - 1].catchers() + catchStr;
+                return CatchArity.values()[this.ordinal() - 1].catchers() +
+                        catchStr;
             }
         }
     }
@@ -98,31 +93,36 @@
         for (CatchArity ca : CatchArity.values()) {
             for (StatementKind stmt0 : StatementKind.values()) {
                 if (ca.ordinal() == 0) {
-                    new T7093325(ca, stmt0).compileAndCheck();
+                    pool.execute(new T7093325(ca, stmt0));
                     continue;
                 }
                 for (StatementKind stmt1 : StatementKind.values()) {
                     if (ca.ordinal() == 1) {
-                        new T7093325(ca, stmt0, stmt1).compileAndCheck();
+                        pool.execute(new T7093325(ca, stmt0, stmt1));
                         continue;
                     }
                     for (StatementKind stmt2 : StatementKind.values()) {
                         if (ca.ordinal() == 2) {
-                            new T7093325(ca, stmt0, stmt1, stmt2).compileAndCheck();
+                            pool.execute(new T7093325(ca, stmt0, stmt1, stmt2));
                             continue;
                         }
                         for (StatementKind stmt3 : StatementKind.values()) {
                             if (ca.ordinal() == 3) {
-                                new T7093325(ca, stmt0, stmt1, stmt2, stmt3).compileAndCheck();
+                                pool.execute(
+                                    new T7093325(ca, stmt0, stmt1, stmt2, stmt3));
                                 continue;
                             }
                             for (StatementKind stmt4 : StatementKind.values()) {
                                 if (ca.ordinal() == 4) {
-                                    new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4).compileAndCheck();
+                                    pool.execute(
+                                        new T7093325(ca, stmt0, stmt1,
+                                                     stmt2, stmt3, stmt4));
                                     continue;
                                 }
                                 for (StatementKind stmt5 : StatementKind.values()) {
-                                    new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4, stmt5).compileAndCheck();
+                                    pool.execute(
+                                        new T7093325(ca, stmt0, stmt1, stmt2,
+                                                     stmt3, stmt4, stmt5));
                                 }
                             }
                         }
@@ -131,7 +131,7 @@
             }
         }
 
-        System.out.println("Total checks made: " + checkCount);
+        checkAfterExec();
     }
 
     /** instance decls **/
@@ -144,17 +144,18 @@
         this.stmts = stmts;
     }
 
-    void compileAndCheck() throws Exception {
+    @Override
+    public void run() {
+        int id = checkCount.incrementAndGet();
         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
-        JavaSource source = new JavaSource();
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, null,
+        JavaSource source = new JavaSource(id);
+        JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), null,
                 null, null, Arrays.asList(source));
         ct.call();
-        verifyBytecode(source);
+        verifyBytecode(source, id);
     }
 
-    void verifyBytecode(JavaSource source) {
-        checkCount++;
+    void verifyBytecode(JavaSource source, int id) {
         boolean lastInlined = false;
         boolean hasCode = false;
         int gapsCount = 0;
@@ -172,11 +173,12 @@
 
         //System.out.printf("gaps %d \n %s \n", gapsCount, source.toString());
 
-        File compiledTest = new File("Test.class");
+        File compiledTest = new File(String.format("Test%s.class", id));
         try {
             ClassFile cf = ClassFile.read(compiledTest);
             if (cf == null) {
-                throw new Error("Classfile not found: " + compiledTest.getName());
+                throw new Error("Classfile not found: " +
+                                compiledTest.getName());
             }
 
             Method test_method = null;
@@ -232,7 +234,7 @@
                 "class C extends RuntimeException {} \n" +
                 "class D extends RuntimeException {} \n" +
                 "class E extends RuntimeException {} \n" +
-                "class Test {\n" +
+                "class Test#ID {\n" +
                 "   void test() {\n" +
                 "   try { #S0 } #C finally { System.out.println(); }\n" +
                 "   }\n" +
@@ -240,10 +242,12 @@
 
         String source;
 
-        public JavaSource() {
-            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+        public JavaSource(int id) {
+            super(URI.create(String.format("myfo:/Test%s.java", id)),
+                  JavaFileObject.Kind.SOURCE);
             source = source_template.replace("#C", ca.catchers());
             source = source.replace("#S0", stmts[0].stmt);
+            source = source.replace("#ID", String.valueOf(id));
             for (int i = 1; i < ca.ordinal() + 1; i++) {
                 source = source.replace("#S" + i, stmts[i].stmt);
             }
@@ -259,4 +263,5 @@
             return source;
         }
     }
+
 }
--- a/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,23 +25,26 @@
  * @test
  * @bug 8002099
  * @summary Add support for intersection types in cast expression
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main/timeout=360 IntersectionTypeCastTest
  */
 
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.ListBuffer;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
 import javax.tools.ToolProvider;
 
-public class IntersectionTypeCastTest {
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
 
-    static int checkCount = 0;
+public class IntersectionTypeCastTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     interface Type {
         boolean subtypeOf(Type that);
@@ -59,7 +62,8 @@
         String typeStr;
         InterfaceKind superInterface;
 
-        InterfaceKind(String declStr, String typeStr, InterfaceKind superInterface) {
+        InterfaceKind(String declStr, String typeStr,
+                InterfaceKind superInterface) {
             this.declStr = declStr;
             this.typeStr = typeStr;
             this.superInterface = superInterface;
@@ -67,7 +71,8 @@
 
         @Override
         public boolean subtypeOf(Type that) {
-            return this == that || superInterface == that || that == ClassKind.OBJECT;
+            return this == that || superInterface == that ||
+                   that == ClassKind.OBJECT;
         }
 
         @Override
@@ -88,19 +93,27 @@
 
     enum ClassKind implements Type {
         OBJECT(null, "Object"),
-        CA("#M class CA implements A { }\n", "CA", InterfaceKind.A),
-        CB("#M class CB implements B { }\n", "CB", InterfaceKind.B),
-        CAB("#M class CAB implements A, B { }\n", "CAB", InterfaceKind.A, InterfaceKind.B),
-        CC("#M class CC implements C { }\n", "CC", InterfaceKind.C, InterfaceKind.A),
-        CCA("#M class CCA implements C, A { }\n", "CCA", InterfaceKind.C, InterfaceKind.A),
-        CCB("#M class CCB implements C, B { }\n", "CCB", InterfaceKind.C, InterfaceKind.A, InterfaceKind.B),
-        CCAB("#M class CCAB implements C, A, B { }\n", "CCAB", InterfaceKind.C, InterfaceKind.A, InterfaceKind.B);
+        CA("#M class CA implements A { }\n", "CA",
+           InterfaceKind.A),
+        CB("#M class CB implements B { }\n", "CB",
+           InterfaceKind.B),
+        CAB("#M class CAB implements A, B { }\n", "CAB",
+            InterfaceKind.A, InterfaceKind.B),
+        CC("#M class CC implements C { }\n", "CC",
+           InterfaceKind.C, InterfaceKind.A),
+        CCA("#M class CCA implements C, A { }\n", "CCA",
+            InterfaceKind.C, InterfaceKind.A),
+        CCB("#M class CCB implements C, B { }\n", "CCB",
+            InterfaceKind.C, InterfaceKind.A, InterfaceKind.B),
+        CCAB("#M class CCAB implements C, A, B { }\n", "CCAB",
+             InterfaceKind.C, InterfaceKind.A, InterfaceKind.B);
 
         String declTemplate;
         String typeStr;
         List<InterfaceKind> superInterfaces;
 
-        ClassKind(String declTemplate, String typeStr, InterfaceKind... superInterfaces) {
+        ClassKind(String declTemplate, String typeStr,
+                InterfaceKind... superInterfaces) {
             this.declTemplate = declTemplate;
             this.typeStr = typeStr;
             this.superInterfaces = List.from(superInterfaces);
@@ -114,7 +127,8 @@
 
         @Override
         public boolean subtypeOf(Type that) {
-            return this == that || superInterfaces.contains(that) || that == OBJECT;
+            return this == that || superInterfaces.contains(that) ||
+                    that == OBJECT;
         }
 
         @Override
@@ -170,9 +184,11 @@
         }
 
         String getCast() {
-            String temp = kind.castTemplate.replaceAll("#C", types[0].asString());
+            String temp = kind.castTemplate.replaceAll("#C",
+                    types[0].asString());
             for (int i = 0; i < kind.interfaceBounds ; i++) {
-                temp = temp.replace(String.format("#I%d", i), types[i + 1].asString());
+                temp = temp.replace(String.format("#I%d", i),
+                                    types[i + 1].asString());
             }
             return temp;
         }
@@ -195,7 +211,8 @@
                             t1.subtypeOf(t2) ||
                             t2.subtypeOf(t1) ||
                             (t1.isInterface() && t2.isInterface()) || //side-cast (1)
-                            (mod == ModifierKind.NONE && (t1.isInterface() != t2.isInterface())); //side-cast (2)
+                            (mod == ModifierKind.NONE &&
+                            (t1.isInterface() != t2.isInterface())); //side-cast (2)
                     if (!compat) return false;
                 }
             }
@@ -204,18 +221,15 @@
     }
 
     public static void main(String... args) throws Exception {
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (ModifierKind mod : ModifierKind.values()) {
             for (CastInfo cast1 : allCastInfo()) {
                 for (CastInfo cast2 : allCastInfo()) {
-                    new IntersectionTypeCastTest(mod, cast1, cast2).run(comp, fm);
+                    pool.execute(
+                        new IntersectionTypeCastTest(mod, cast1, cast2));
                 }
             }
         }
-        System.out.println("Total check executed: " + checkCount);
+        checkAfterExec();
     }
 
     static List<CastInfo> allCastInfo() {
@@ -235,11 +249,14 @@
                         } else {
                             for (InterfaceKind intf2 : InterfaceKind.values()) {
                                 if (kind.interfaceBounds == 2) {
-                                    buf.append(new CastInfo(kind, clazz, intf1, intf2));
+                                    buf.append(
+                                            new CastInfo(kind, clazz, intf1, intf2));
                                     continue;
                                 } else {
                                     for (InterfaceKind intf3 : InterfaceKind.values()) {
-                                        buf.append(new CastInfo(kind, clazz, intf1, intf2, intf3));
+                                        buf.append(
+                                                new CastInfo(kind, clazz, intf1,
+                                                             intf2, intf3));
                                         continue;
                                     }
                                 }
@@ -265,6 +282,22 @@
         this.diagChecker = new DiagnosticChecker();
     }
 
+    @Override
+    public void run() {
+        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+
+        JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), diagChecker,
+                Arrays.asList("-XDallowIntersectionTypes"),
+                null, Arrays.asList(source));
+        try {
+            ct.analyze();
+        } catch (Throwable ex) {
+            throw new AssertionError("Error thrown when compiling the following code:\n" +
+                    source.getCharContent(true));
+        }
+        check();
+    }
+
     class JavaSource extends SimpleJavaFileObject {
 
         String bodyTemplate = "class Test {\n" +
@@ -282,7 +315,8 @@
             for (InterfaceKind ik : InterfaceKind.values()) {
                 source += ik.declStr;
             }
-            source += bodyTemplate.replaceAll("#C1", cast1.getCast()).replaceAll("#C2", cast2.getCast());
+            source += bodyTemplate.replaceAll("#C1", cast1.getCast()).
+                    replaceAll("#C2", cast2.getCast());
         }
 
         @Override
@@ -291,21 +325,11 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
-                Arrays.asList("-XDallowIntersectionTypes"), null, Arrays.asList(source));
-        try {
-            ct.analyze();
-        } catch (Throwable ex) {
-            throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
-        }
-        check();
-    }
+    void check() {
+        checkCount.incrementAndGet();
 
-    void check() {
-        checkCount++;
-
-        boolean errorExpected = cast1.hasDuplicateTypes() || cast2.hasDuplicateTypes();
+        boolean errorExpected = cast1.hasDuplicateTypes() ||
+                cast2.hasDuplicateTypes();
 
         errorExpected |= !cast2.compatibleWith(mod, cast1);
 
@@ -317,7 +341,8 @@
         }
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound;
 
@@ -327,4 +352,5 @@
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,25 +24,25 @@
 /*
  * @test
  * @summary Automatic test for checking correctness of default super/this resolution
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main TestDefaultSuperCall
  */
 
-import com.sun.source.util.JavacTask;
 import java.net.URI;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
 
-public class TestDefaultSuperCall {
-
-    static int checkCount = 0;
+public class TestDefaultSuperCall
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum InterfaceKind {
         DEFAULT("interface A extends B { default void m() { } }"),
@@ -212,7 +212,7 @@
         List<String> elementsWithMethod;
 
         Shape(ElementKind... elements) {
-            System.err.println("elements = " + Arrays.toString(elements));
+            errWriter.println("elements = " + Arrays.toString(elements));
             enclosingElements = new ArrayList<>();
             enclosingNames = new ArrayList<>();
             elementsWithMethod = new ArrayList<>();
@@ -231,28 +231,26 @@
                     elementsWithMethod.add(prevName);
                 }
                 String element = ek.templateDecl.replaceAll("#N", name);
-                shapeStr = shapeStr == null ? element : shapeStr.replaceAll("#B", element);
+                shapeStr = shapeStr ==
+                        null ? element : shapeStr.replaceAll("#B", element);
                 prevName = name;
             }
         }
 
         String getShape(QualifierKind qk, ExprKind ek) {
             String methName = ek == ExprKind.THIS ? "test" : "m";
-            String call = qk.getQualifier(this) + "." + ek.exprStr + "." + methName + "();";
+            String call = qk.getQualifier(this) + "." +
+                    ek.exprStr + "." + methName + "();";
             return shapeStr.replaceAll("#B", call);
         }
 
         String enclosingAt(int index) {
-            return index < enclosingNames.size() ? enclosingNames.get(index) : "BAD";
+            return index < enclosingNames.size() ?
+                    enclosingNames.get(index) : "BAD";
         }
     }
 
     public static void main(String... args) throws Exception {
-
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (InterfaceKind ik : InterfaceKind.values()) {
             for (PruneKind pk : PruneKind.values()) {
                 for (ElementKind ek1 : ElementKind.values()) {
@@ -264,10 +262,14 @@
                             for (ElementKind ek4 : ElementKind.values()) {
                                 if (!ek4.isAllowedEnclosing(ek3, false)) continue;
                                 for (ElementKind ek5 : ElementKind.values()) {
-                                    if (!ek5.isAllowedEnclosing(ek4, false) || ek5.isClassDecl()) continue;
+                                    if (!ek5.isAllowedEnclosing(ek4, false) ||
+                                            ek5.isClassDecl()) continue;
                                     for (QualifierKind qk : QualifierKind.values()) {
                                         for (ExprKind ek : ExprKind.values()) {
-                                            new TestDefaultSuperCall(ik, pk, new Shape(ek1, ek2, ek3, ek4, ek5), qk, ek).run(comp, fm);
+                                            pool.execute(
+                                                    new TestDefaultSuperCall(ik, pk,
+                                                    new Shape(ek1, ek2, ek3,
+                                                    ek4, ek5), qk, ek));
                                         }
                                     }
                                 }
@@ -277,7 +279,8 @@
                 }
             }
         }
-        System.out.println("Total check executed: " + checkCount);
+
+        checkAfterExec();
     }
 
     InterfaceKind ik;
@@ -288,7 +291,8 @@
     JavaSource source;
     DiagnosticChecker diagChecker;
 
-    TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh, QualifierKind qk, ExprKind ek) {
+    TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh,
+            QualifierKind qk, ExprKind ek) {
         this.ik = ik;
         this.pk = pk;
         this.sh = sh;
@@ -321,13 +325,14 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+    public void run() {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
                 null, null, Arrays.asList(source));
         try {
             ct.analyze();
         } catch (Throwable ex) {
-            throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+            processException(ex);
+            return;
         }
         check();
     }
@@ -370,7 +375,8 @@
 
             int lastIdx = sh.enclosingElements.size() - 1;
             boolean found = lastIdx == -1 ? false :
-                    sh.enclosingElements.get(lastIdx).hasSuper() && qk.allowSuperCall(ik, pk);
+                    sh.enclosingElements.get(lastIdx).hasSuper() &&
+                    qk.allowSuperCall(ik, pk);
 
             errorExpected |= !found;
             if (!found) {
@@ -378,9 +384,10 @@
             }
         }
 
-        checkCount++;
+        checkCount.incrementAndGet();
         if (diagChecker.errorFound != errorExpected) {
-            throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
+            throw new AssertionError("Problem when compiling source:\n" +
+                    source.getCharContent(true) +
                     "\nenclosingElems: " + sh.enclosingElements +
                     "\nenclosingNames: " + sh.enclosingNames +
                     "\nelementsWithMethod: " + sh.elementsWithMethod +
@@ -392,15 +399,17 @@
         }
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound;
 
         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
-                System.err.println(diagnostic.getMessage(Locale.getDefault()));
+                errWriter.println(diagnostic.getMessage(Locale.getDefault()));
                 errorFound = true;
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/failover/CheckAttributedTree.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,7 +21,15 @@
  * questions.
  */
 
-import com.sun.source.util.TaskEvent;
+/*
+ * @test
+ * @bug 6970584
+ * @summary assorted position errors in compiler syntax trees
+ * @library ../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main CheckAttributedTree -q -r -et ERRONEOUS .
+ */
+
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Dimension;
@@ -34,6 +42,20 @@
 import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.lang.model.element.Element;
 import javax.swing.DefaultComboBoxModel;
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
@@ -49,23 +71,14 @@
 import javax.swing.text.BadLocationException;
 import javax.swing.text.DefaultHighlighter;
 import javax.swing.text.Highlighter;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.List;
 import javax.tools.Diagnostic;
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
 
 import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.TaskEvent;
 import com.sun.source.util.JavacTask;
 import com.sun.source.util.TaskListener;
-import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.tree.EndPosTable;
@@ -76,11 +89,6 @@
 import com.sun.tools.javac.tree.TreeScanner;
 import com.sun.tools.javac.util.Pair;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import javax.lang.model.element.Element;
-
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /**
@@ -95,13 +103,7 @@
  * covering any new language features that may be tested in this test suite.
  */
 
-/*
- * @test
- * @bug 6970584
- * @summary assorted position errors in compiler syntax trees
- * @run main CheckAttributedTree -q -r -et ERRONEOUS .
- */
-public class CheckAttributedTree {
+public class CheckAttributedTree extends JavacTestingAbstractThreadedTest {
     /**
      * Main entry point.
      * If test.src is set, program runs in jtreg mode, and will throw an Error
@@ -110,9 +112,10 @@
      * args is the value of ${test.src}. In jtreg mode, the -r option can be
      * given to change the default base directory to the root test directory.
      */
-    public static void main(String... args) {
+    public static void main(String... args) throws Exception {
         String testSrc = System.getProperty("test.src");
         File baseDir = (testSrc == null) ? null : new File(testSrc);
+        throwAssertionOnError = false;
         boolean ok = new CheckAttributedTree().run(baseDir, args);
         if (!ok) {
             if (testSrc != null)  // jtreg mode
@@ -130,7 +133,7 @@
      * @param args command line args
      * @return true if successful or in gui mode
      */
-    boolean run(File baseDir, String... args) {
+    boolean run(File baseDir, String... args) throws Exception {
         if (args.length == 0) {
             usage(System.out);
             return true;
@@ -145,8 +148,10 @@
                 gui = true;
             else if (arg.equals("-q"))
                 quiet = true;
-            else if (arg.equals("-v"))
+            else if (arg.equals("-v")) {
                 verbose = true;
+                printAll = true;
+            }
             else if (arg.equals("-t") && i + 1 < args.length)
                 tags.add(args[++i]);
             else if (arg.equals("-ef") && i + 1 < args.length)
@@ -179,12 +184,11 @@
                 error("File not found: " + file);
         }
 
-        if (fileCount != 1)
-            System.err.println(fileCount + " files read");
-        if (errors > 0)
-            System.err.println(errors + " errors");
+        if (fileCount.get() != 1)
+            errWriter.println(fileCount + " files read");
+        checkAfterExec(false);
 
-        return (gui || errors == 0);
+        return (gui || errCount.get() == 0);
     }
 
     /**
@@ -215,7 +219,7 @@
      * for java files.
      * @param file the file or directory to test
      */
-    void test(File file) {
+    void test(final File file) {
         if (excludeFiles.contains(file)) {
             if (!quiet)
                 error("File " + file + " excluded");
@@ -230,20 +234,24 @@
         }
 
         if (file.isFile() && file.getName().endsWith(".java")) {
-            try {
-                if (verbose)
-                    System.err.println(file);
-                fileCount++;
-                NPETester p = new NPETester();
-                p.test(read(file));
-            } catch (AttributionException e) {
-                if (!quiet) {
-                    error("Error attributing " + file + "\n" + e.getMessage());
+            pool.execute(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (verbose)
+                            errWriter.println(file);
+                        fileCount.incrementAndGet();
+                        NPETester p = new NPETester();
+                        p.test(read(file));
+                    } catch (AttributionException e) {
+                        if (!quiet) {
+                            error("Error attributing " + file + "\n" + e.getMessage());
+                        }
+                    } catch (IOException e) {
+                        error("Error reading " + file + ": " + e);
+                    }
                 }
-            } catch (IOException e) {
-                error("Error reading " + file + ": " + e);
-            }
-            return;
+            });
         }
 
         if (!quiet)
@@ -254,8 +262,6 @@
     StringWriter sw = new StringWriter();
     PrintWriter pw = new PrintWriter(sw);
     Reporter r = new Reporter(pw);
-    JavacTool tool = JavacTool.create();
-    StandardJavaFileManager fm = tool.getStandardFileManager(r, null, null);
 
     /**
      * Read a file.
@@ -265,11 +271,10 @@
      * @throws TreePosTest.ParseException if any errors occur while parsing the file
      */
     List<Pair<JCCompilationUnit, JCTree>> read(File file) throws IOException, AttributionException {
-        JavacTool tool = JavacTool.create();
         r.errors = 0;
-        Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(file);
+        Iterable<? extends JavaFileObject> files = fm.get().getJavaFileObjects(file);
         String[] opts = { "-XDshouldStopPolicy=ATTR", "-XDverboseCompilePolicy" };
-        JavacTask task = tool.getTask(pw, fm, r, Arrays.asList(opts), null, files);
+        JavacTask task = (JavacTask)comp.getTask(pw, fm.get(), r, Arrays.asList(opts), null, files);
         final List<Element> analyzedElems = new ArrayList<>();
         task.setTaskListener(new TaskListener() {
             public void started(TaskEvent e) {
@@ -308,13 +313,9 @@
      */
     void error(String msg) {
         System.err.println(msg);
-        errors++;
+        errCount.incrementAndGet();
     }
 
-    /** Number of files that have been analyzed. */
-    int fileCount;
-    /** Number of errors reported. */
-    int errors;
     /** Flag: don't report irrelevant files. */
     boolean quiet;
     /** Flag: show errors in GUI viewer. */
@@ -385,7 +386,8 @@
                         viewer = new Viewer();
                     viewer.addEntry(sourcefile, label, encl, self);
                 }
-                error(label + self.toString() + " encl: " + encl.toString() + " in file: " + sourcefile + "  " + self.tree);
+                error(label + self.toString() + " encl: " + encl.toString() +
+                        " in file: " + sourcefile + "  " + self.tree);
             }
         }
 
@@ -754,4 +756,8 @@
             final Info self;
         }
     }
+
+    /** Number of files that have been analyzed. */
+    static AtomicInteger fileCount = new AtomicInteger();
+
 }
--- a/langtools/test/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,21 +25,21 @@
  * @test
  * @bug 7046778
  * @summary Project Coin: problem with diamond and member inner classes
+ * @library ../../../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main DiamondAndInnerClassTest
  */
 
 import com.sun.source.util.JavacTask;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
 
-public class DiamondAndInnerClassTest {
-
-    static int checkCount = 0;
+public class DiamondAndInnerClassTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum TypeArgumentKind {
         NONE(""),
@@ -151,11 +151,6 @@
     }
 
     public static void main(String... args) throws Exception {
-
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (InnerClassDeclArity innerClassDeclArity : InnerClassDeclArity.values()) {
             for (TypeQualifierArity declType : TypeQualifierArity.values()) {
                 if (!declType.matches(innerClassDeclArity)) continue;
@@ -168,53 +163,79 @@
                             //no diamond on decl site
                             if (taDecl1 == TypeArgumentKind.DIAMOND) continue;
                             for (TypeArgumentKind taSite1 : TypeArgumentKind.values()) {
-                                boolean isSiteRaw = taSite1 == TypeArgumentKind.NONE;
+                                boolean isSiteRaw =
+                                        taSite1 == TypeArgumentKind.NONE;
                                 //diamond only allowed on the last type qualifier
                                 if (taSite1 == TypeArgumentKind.DIAMOND &&
-                                        innerClassDeclArity != InnerClassDeclArity.ONE) continue;
+                                        innerClassDeclArity !=
+                                        InnerClassDeclArity.ONE)
+                                    continue;
                                 for (ArgumentKind arg1 : ArgumentKind.values()) {
                                     if (innerClassDeclArity == innerClassDeclArity.ONE) {
-                                        new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
-                                                argList, new TypeArgumentKind[] {taDecl1},
-                                                new TypeArgumentKind[] {taSite1}, new ArgumentKind[] {arg1}).run(comp, fm);
+                                        pool.execute(
+                                                new DiamondAndInnerClassTest(
+                                                innerClassDeclArity, declType,
+                                                newClassType, argList,
+                                                new TypeArgumentKind[] {taDecl1},
+                                                new TypeArgumentKind[] {taSite1},
+                                                new ArgumentKind[] {arg1}));
                                         continue;
                                     }
                                     for (TypeArgumentKind taDecl2 : TypeArgumentKind.values()) {
                                         //no rare types
-                                        if (isDeclRaw != (taDecl2 == TypeArgumentKind.NONE)) continue;
+                                        if (isDeclRaw != (taDecl2 == TypeArgumentKind.NONE))
+                                            continue;
                                         //no diamond on decl site
-                                        if (taDecl2 == TypeArgumentKind.DIAMOND) continue;
+                                        if (taDecl2 == TypeArgumentKind.DIAMOND)
+                                            continue;
                                         for (TypeArgumentKind taSite2 : TypeArgumentKind.values()) {
                                             //no rare types
-                                            if (isSiteRaw != (taSite2 == TypeArgumentKind.NONE)) continue;
+                                            if (isSiteRaw != (taSite2 == TypeArgumentKind.NONE))
+                                                continue;
                                             //diamond only allowed on the last type qualifier
                                             if (taSite2 == TypeArgumentKind.DIAMOND &&
-                                                    innerClassDeclArity != InnerClassDeclArity.TWO) continue;
+                                                    innerClassDeclArity != InnerClassDeclArity.TWO)
+                                                continue;
                                             for (ArgumentKind arg2 : ArgumentKind.values()) {
                                                 if (innerClassDeclArity == innerClassDeclArity.TWO) {
-                                                    new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
-                                                            argList, new TypeArgumentKind[] {taDecl1, taDecl2},
+                                                    pool.execute(
+                                                            new DiamondAndInnerClassTest(
+                                                            innerClassDeclArity,
+                                                            declType,
+                                                            newClassType,
+                                                            argList,
+                                                            new TypeArgumentKind[] {taDecl1, taDecl2},
                                                             new TypeArgumentKind[] {taSite1, taSite2},
-                                                            new ArgumentKind[] {arg1, arg2}).run(comp, fm);
+                                                            new ArgumentKind[] {arg1, arg2}));
                                                     continue;
                                                 }
                                                 for (TypeArgumentKind taDecl3 : TypeArgumentKind.values()) {
                                                     //no rare types
-                                                    if (isDeclRaw != (taDecl3 == TypeArgumentKind.NONE)) continue;
+                                                    if (isDeclRaw != (taDecl3 == TypeArgumentKind.NONE))
+                                                        continue;
                                                     //no diamond on decl site
-                                                    if (taDecl3 == TypeArgumentKind.DIAMOND) continue;
+                                                    if (taDecl3 == TypeArgumentKind.DIAMOND)
+                                                        continue;
                                                     for (TypeArgumentKind taSite3 : TypeArgumentKind.values()) {
                                                         //no rare types
-                                                        if (isSiteRaw != (taSite3 == TypeArgumentKind.NONE)) continue;
+                                                        if (isSiteRaw != (taSite3 == TypeArgumentKind.NONE))
+                                                            continue;
                                                         //diamond only allowed on the last type qualifier
                                                         if (taSite3 == TypeArgumentKind.DIAMOND &&
-                                                                innerClassDeclArity != InnerClassDeclArity.THREE) continue;
+                                                            innerClassDeclArity != InnerClassDeclArity.THREE)
+                                                            continue;
                                                         for (ArgumentKind arg3 : ArgumentKind.values()) {
-                                                            if (innerClassDeclArity == innerClassDeclArity.THREE) {
-                                                                new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
-                                                                        argList, new TypeArgumentKind[] {taDecl1, taDecl2, taDecl3},
+                                                            if (innerClassDeclArity ==
+                                                                    innerClassDeclArity.THREE) {
+                                                                pool.execute(
+                                                                        new DiamondAndInnerClassTest(
+                                                                        innerClassDeclArity,
+                                                                        declType,
+                                                                        newClassType,
+                                                                        argList,
+                                                                        new TypeArgumentKind[] {taDecl1, taDecl2, taDecl3},
                                                                         new TypeArgumentKind[] {taSite1, taSite2, taSite3},
-                                                                        new ArgumentKind[] {arg1, arg2, arg3}).run(comp, fm);
+                                                                        new ArgumentKind[] {arg1, arg2, arg3}));
                                                                 continue;
                                                             }
                                                         }
@@ -230,7 +251,8 @@
                 }
             }
         }
-        System.out.println("Total check executed: " + checkCount);
+
+        checkAfterExec();
     }
 
     InnerClassDeclArity innerClassDeclArity;
@@ -244,9 +266,9 @@
     DiagnosticChecker diagChecker;
 
     DiamondAndInnerClassTest(InnerClassDeclArity innerClassDeclArity,
-            TypeQualifierArity declType, TypeQualifierArity siteType, ArgumentListArity argList,
-            TypeArgumentKind[] declTypeArgumentKinds, TypeArgumentKind[] siteTypeArgumentKinds,
-            ArgumentKind[] argumentKinds) {
+            TypeQualifierArity declType, TypeQualifierArity siteType,
+            ArgumentListArity argList, TypeArgumentKind[] declTypeArgumentKinds,
+            TypeArgumentKind[] siteTypeArgumentKinds, ArgumentKind[] argumentKinds) {
         this.innerClassDeclArity = innerClassDeclArity;
         this.declType = declType;
         this.siteType = siteType;
@@ -267,9 +289,9 @@
         public JavaSource() {
             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
             source = innerClassDeclArity.classDeclStr.replace("#B", bodyTemplate)
-                             .replace("#D", declType.getType(declTypeArgumentKinds))
-                             .replace("#S", siteType.getType(siteTypeArgumentKinds))
-                             .replace("#AL", argList.getArgs(argumentKinds));
+                    .replace("#D", declType.getType(declTypeArgumentKinds))
+                    .replace("#S", siteType.getType(siteTypeArgumentKinds))
+                    .replace("#AL", argList.getArgs(argumentKinds));
         }
 
         @Override
@@ -278,36 +300,39 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+    @Override
+    public void run() {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
                 null, null, Arrays.asList(source));
         try {
             ct.analyze();
         } catch (Throwable ex) {
-            throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
+            throw new AssertionError("Error thrown when compiling the following code:\n" +
+                    source.getCharContent(true));
         }
         check();
     }
 
     void check() {
-        checkCount++;
+        checkCount.incrementAndGet();
 
         boolean errorExpected = false;
 
-        TypeArgumentKind[] expectedArgKinds = new TypeArgumentKind[innerClassDeclArity.n];
+        TypeArgumentKind[] expectedArgKinds =
+                new TypeArgumentKind[innerClassDeclArity.n];
 
         for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
             if (!declTypeArgumentKinds[i].compatible(siteTypeArgumentKinds[i])) {
                 errorExpected = true;
                 break;
             }
-            expectedArgKinds[i] = siteTypeArgumentKinds[i] == TypeArgumentKind.DIAMOND ?
+            expectedArgKinds[i] = siteTypeArgumentKinds[i] ==
+                    TypeArgumentKind.DIAMOND ?
                 declTypeArgumentKinds[i] : siteTypeArgumentKinds[i];
         }
 
         if (!errorExpected) {
             for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
-                //System.out.println("check " + expectedArgKinds[i] + " against " + argumentKinds[i]);
                 if (!expectedArgKinds[i].compatible(argumentKinds[i])) {
                     errorExpected = true;
                     break;
@@ -323,7 +348,8 @@
         }
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound;
 
@@ -333,4 +359,5 @@
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,22 +24,23 @@
 /*
  * @test
  * @bug 7062745
- * @summary  Regression: difference in overload resolution when two methods are maximally specific
+ * @summary  Regression: difference in overload resolution when two methods
+ * are maximally specific
+ * @library ../../../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main GenericOverrideTest
  */
 
-import com.sun.source.util.JavacTask;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
 
-public class GenericOverrideTest {
-
-    static int checkCount = 0;
+public class GenericOverrideTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum SignatureKind {
         NON_GENERIC(""),
@@ -126,11 +127,6 @@
     }
 
     public static void main(String... args) throws Exception {
-
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (SignatureKind sig1 : SignatureKind.values()) {
             for (ReturnTypeKind rt1 : ReturnTypeKind.values()) {
                 for (TypeArgumentKind ta1 : TypeArgumentKind.values()) {
@@ -141,8 +137,12 @@
                                 if (!ta2.compatibleWith(sig2)) continue;
                                 for (ReturnTypeKind rt3 : ReturnTypeKind.values()) {
                                     for (TypeArgumentKind ta3 : TypeArgumentKind.values()) {
-                                        if (!ta3.compatibleWith(SignatureKind.NON_GENERIC)) continue;
-                                        new GenericOverrideTest(sig1, rt1, ta1, sig2, rt2, ta2, rt3, ta3).run(comp, fm);
+                                        if (!ta3.compatibleWith(SignatureKind.NON_GENERIC))
+                                            continue;
+                                        pool.execute(
+                                                new GenericOverrideTest(sig1,
+                                                rt1, ta1, sig2, rt2,
+                                                ta2, rt3, ta3));
                                     }
                                 }
                             }
@@ -151,7 +151,8 @@
                 }
             }
         }
-        System.out.println("Total check executed: " + checkCount);
+
+        checkAfterExec();
     }
 
     SignatureKind sig1, sig2;
@@ -161,7 +162,8 @@
     DiagnosticChecker diagChecker;
 
     GenericOverrideTest(SignatureKind sig1, ReturnTypeKind rt1, TypeArgumentKind ta1,
-            SignatureKind sig2, ReturnTypeKind rt2, TypeArgumentKind ta2, ReturnTypeKind rt3, TypeArgumentKind ta3) {
+            SignatureKind sig2, ReturnTypeKind rt2, TypeArgumentKind ta2,
+            ReturnTypeKind rt3, TypeArgumentKind ta3) {
         this.sig1 = sig1;
         this.sig2 = sig2;
         this.rt1 = rt1;
@@ -204,19 +206,21 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+    @Override
+    public void run() {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
                 null, null, Arrays.asList(source));
         try {
             ct.analyze();
         } catch (Throwable ex) {
-            throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
+            throw new AssertionError("Error thrown when compiling the following code:\n" +
+                    source.getCharContent(true));
         }
         check();
     }
 
     void check() {
-        checkCount++;
+        checkCount.incrementAndGet();
 
         boolean errorExpected = false;
         int mostSpecific = 0;
@@ -234,14 +238,17 @@
         //check that either TA1 <= TA2 or TA2 <= TA1 (unless most specific return found above is raw)
         if (!errorExpected) {
             if (ta1 != ta2) {
-                boolean useStrictCheck = ta1.moreSpecificThan(ta2, true) || ta2.moreSpecificThan(ta1, true);
+                boolean useStrictCheck = ta1.moreSpecificThan(ta2, true) ||
+                        ta2.moreSpecificThan(ta1, true);
                 if (!ta1.moreSpecificThan(ta2, useStrictCheck) &&
                         !ta2.moreSpecificThan(ta1, useStrictCheck)) {
                     errorExpected = true;
                 } else {
                     int mostSpecific2 = ta1.moreSpecificThan(ta2, useStrictCheck) ? 1 : 2;
                     if (mostSpecific != 0 && mostSpecific2 != mostSpecific) {
-                        errorExpected = mostSpecific == 1 ? ta1 != TypeArgumentKind.NONE : ta2 != TypeArgumentKind.NONE;
+                        errorExpected = mostSpecific == 1 ?
+                                ta1 != TypeArgumentKind.NONE :
+                                ta2 != TypeArgumentKind.NONE;
                     } else {
                         mostSpecific = mostSpecific2;
                     }
@@ -273,7 +280,8 @@
         }
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound;
 
@@ -283,4 +291,5 @@
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,20 +27,24 @@
  * @summary Add lambda tests
  *  perform several automated checks in lambda conversion, esp. around accessibility
  * @author  Maurizio Cimadamore
+ * @library ../lib
+ * @build JavacTestingAbstractThreadedTest
  * @run main FunctionalInterfaceConversionTest
  */
 
-import com.sun.source.util.JavacTask;
+import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
 import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
 
-public class FunctionalInterfaceConversionTest {
+public class FunctionalInterfaceConversionTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum PackageKind {
         NO_PKG(""),
@@ -139,8 +143,6 @@
     }
 
     public static void main(String[] args) throws Exception {
-        final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
         for (PackageKind samPkg : PackageKind.values()) {
             for (ModifierKind modKind : ModifierKind.values()) {
                 for (SamKind samKind : SamKind.values()) {
@@ -150,8 +152,11 @@
                                 for (TypeKind argType : TypeKind.values()) {
                                     for (TypeKind thrownType : TypeKind.values()) {
                                         for (ExprKind exprKind : ExprKind.values()) {
-                                            new FunctionalInterfaceConversionTest(samPkg, modKind, samKind,
-                                                    samMeth, clientMeth, retType, argType, thrownType, exprKind).test(comp, fm);
+                                            pool.execute(
+                                                new FunctionalInterfaceConversionTest(
+                                                    samPkg, modKind, samKind,
+                                                    samMeth, clientMeth, retType,
+                                                    argType, thrownType, exprKind));
                                         }
                                     }
                                 }
@@ -161,6 +166,8 @@
                 }
             }
         }
+
+        checkAfterExec(false);
     }
 
     PackageKind samPkg;
@@ -175,24 +182,30 @@
     DiagnosticChecker dc;
 
     SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
+        @Override
         public String toString() {
             return template.replaceAll("#P", samPkg.getPkgDecl()).
-                    replaceAll("#C", samKind.getSam(samMeth.getMethod(retType, argType, thrownType)));
+                    replaceAll("#C", samKind.getSam(
+                    samMeth.getMethod(retType, argType, thrownType)));
         }
     };
 
-    SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
-                                                   "#P\n #M class PackageClass extends Exception { }") {
+    SourceFile pkgClassSourceFile =
+            new SourceFile("PackageClass.java",
+                           "#P\n #M class PackageClass extends Exception { }") {
+        @Override
         public String toString() {
             return template.replaceAll("#P", samPkg.getPkgDecl()).
                     replaceAll("#M", modKind.modifier_str);
         }
     };
 
-    SourceFile clientSourceFile = new SourceFile("Client.java",
-                                                 "#I\n abstract class Client { \n" +
-                                                 "  Sam s = #E;\n" +
-                                                 "  #M \n }") {
+    SourceFile clientSourceFile =
+            new SourceFile("Client.java",
+                           "#I\n abstract class Client { \n" +
+                           "  Sam s = #E;\n" +
+                           "  #M \n }") {
+        @Override
         public String toString() {
             return template.replaceAll("#I", samPkg.getImportStat())
                     .replaceAll("#E", exprKind.exprStr)
@@ -200,9 +213,10 @@
         }
     };
 
-    FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
-            MethodKind samMeth, MethodKind clientMeth, TypeKind retType, TypeKind argType,
-            TypeKind thrownType, ExprKind exprKind) {
+    FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind,
+            SamKind samKind, MethodKind samMeth, MethodKind clientMeth,
+            TypeKind retType, TypeKind argType, TypeKind thrownType,
+            ExprKind exprKind) {
         this.samPkg = samPkg;
         this.modKind = modKind;
         this.samKind = samKind;
@@ -215,12 +229,20 @@
         this.dc = new DiagnosticChecker();
     }
 
-    void test(JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)comp.getTask(null, fm, dc,
-                null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
-        ct.analyze();
+    @Override
+    public void run() {
+        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+
+        JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), dc, null, null,
+                Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
+        try {
+            ct.analyze();
+        } catch (IOException ex) {
+            throw new AssertionError("Test failing with cause", ex.getCause());
+        }
         if (dc.errorFound == checkSamConversion()) {
-            throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
+            throw new AssertionError(samSourceFile + "\n\n" +
+                pkgClassSourceFile + "\n\n" + clientSourceFile);
         }
     }
 
@@ -264,13 +286,16 @@
             return toString();
         }
 
+        @Override
         public abstract String toString();
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound = false;
 
+        @Override
         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
                 errorFound = true;
--- a/langtools/test/tools/javac/lambda/LambdaParserTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/LambdaParserTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,21 +27,21 @@
  * @bug 8003280
  * @summary Add lambda tests
  *  Add parser support for lambda expressions
+ * @library ../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main LambdaParserTest
  */
 
-import com.sun.source.util.JavacTask;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
 
-public class LambdaParserTest {
-
-    static int checkCount = 0;
+public class LambdaParserTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum LambdaKind {
         NILARY_EXPR("()->x"),
@@ -173,25 +173,26 @@
     }
 
     public static void main(String... args) throws Exception {
-
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (LambdaKind lk : LambdaKind.values()) {
             for (LambdaParameterKind pk1 : LambdaParameterKind.values()) {
-                if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT) continue;
+                if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT)
+                    continue;
                 for (LambdaParameterKind pk2 : LambdaParameterKind.values()) {
-                    if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT) continue;
+                    if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT)
+                        continue;
                     for (ModifierKind mk1 : ModifierKind.values()) {
-                        if (mk1 != ModifierKind.NONE && lk.isShort()) continue;
-                        if (lk.arity() < 1 && mk1 != ModifierKind.NONE) continue;
+                        if (mk1 != ModifierKind.NONE && lk.isShort())
+                            continue;
+                        if (lk.arity() < 1 && mk1 != ModifierKind.NONE)
+                            continue;
                         for (ModifierKind mk2 : ModifierKind.values()) {
-                            if (lk.arity() < 2 && mk2 != ModifierKind.NONE) continue;
+                            if (lk.arity() < 2 && mk2 != ModifierKind.NONE)
+                                continue;
                             for (SubExprKind sk : SubExprKind.values()) {
                                 for (ExprKind ek : ExprKind.values()) {
-                                    new LambdaParserTest(pk1, pk2, mk1, mk2, lk, sk, ek)
-                                            .run(comp, fm);
+                                    pool.execute(
+                                        new LambdaParserTest(pk1, pk2, mk1,
+                                                             mk2, lk, sk, ek));
                                 }
                             }
                         }
@@ -199,7 +200,8 @@
                 }
             }
         }
-        System.out.println("Total check executed: " + checkCount);
+
+        checkAfterExec();
     }
 
     LambdaParameterKind pk1;
@@ -212,8 +214,9 @@
     JavaSource source;
     DiagnosticChecker diagChecker;
 
-    LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2, ModifierKind mk1,
-            ModifierKind mk2, LambdaKind lk, SubExprKind sk, ExprKind ek) {
+    LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2,
+            ModifierKind mk1, ModifierKind mk2, LambdaKind lk,
+            SubExprKind sk, ExprKind ek) {
         this.pk1 = pk1;
         this.pk2 = pk2;
         this.mk1 = mk1;
@@ -235,7 +238,8 @@
 
         public JavaSource() {
             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
-            source = template.replaceAll("#E", ek.expressionString(pk1, pk2, mk1, mk2, lk, sk));
+            source = template.replaceAll("#E",
+                    ek.expressionString(pk1, pk2, mk1, mk2, lk, sk));
         }
 
         @Override
@@ -244,19 +248,20 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+    public void run() {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
                 null, null, Arrays.asList(source));
         try {
             ct.parse();
         } catch (Throwable ex) {
-            throw new AssertionError("Error thrown when parsing the following source:\n" + source.getCharContent(true));
+            processException(ex);
+            return;
         }
         check();
     }
 
     void check() {
-        checkCount++;
+        checkCount.incrementAndGet();
 
         boolean errorExpected = (lk.arity() > 0 && !mk1.compatibleWith(pk1)) ||
                 (lk.arity() > 1 && !mk2.compatibleWith(pk2));
@@ -275,7 +280,8 @@
         }
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound;
 
@@ -285,4 +291,5 @@
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,21 +27,21 @@
  * @bug 8003280
  * @summary Add lambda tests
  *  Add parser support for method references
+ * @library ../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main MethodReferenceParserTest
  */
 
-import com.sun.source.util.JavacTask;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
 
-public class MethodReferenceParserTest {
-
-    static int checkCount = 0;
+public class MethodReferenceParserTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum ReferenceKind {
         METHOD_REF("#Q::#Gm"),
@@ -88,7 +88,8 @@
             this.contextTemplate = contextTemplate;
         }
 
-        String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) {
+        String contextString(ExprKind ek, ReferenceKind rk, QualifierKind qk,
+                GenericKind gk, SubExprKind sk) {
             return contextTemplate.replaceAll("#E", ek.expressionString(rk, qk, gk, sk));
         }
     }
@@ -165,25 +166,21 @@
     }
 
     public static void main(String... args) throws Exception {
-
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (ReferenceKind rk : ReferenceKind.values()) {
             for (QualifierKind qk : QualifierKind.values()) {
                 for (GenericKind gk : GenericKind.values()) {
                     for (SubExprKind sk : SubExprKind.values()) {
                         for (ExprKind ek : ExprKind.values()) {
                             for (ContextKind ck : ContextKind.values()) {
-                                new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck).run(comp, fm);
+                                pool.execute(new MethodReferenceParserTest(rk, qk, gk, sk, ek, ck));
                             }
                         }
                     }
                 }
             }
         }
-        System.out.println("Total check executed: " + checkCount);
+
+        checkAfterExec();
     }
 
     ReferenceKind rk;
@@ -227,19 +224,21 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+    @Override
+    public void run() {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
                 null, null, Arrays.asList(source));
         try {
             ct.parse();
         } catch (Throwable ex) {
-            throw new AssertionError("Error thrown when parsing the following source:\n" + source.getCharContent(true));
+            processException(ex);
+            return;
         }
         check();
     }
 
     void check() {
-        checkCount++;
+        checkCount.incrementAndGet();
 
         if (diagChecker.errorFound != rk.erroneous()) {
             throw new Error("invalid diagnostics for source:\n" +
@@ -259,4 +258,5 @@
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/lambda/TargetType21.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType21.java	Wed Jan 16 11:58:15 2013 -0800
@@ -25,7 +25,7 @@
     <R,A> void call(SAM3<R,A> sam) { }
 
     void test() {
-        call(x -> { throw new Exception(); }); //ok - resolves to call(SAM1)
+        call(x -> { throw new Exception(); }); //ambiguous
         call(x -> { System.out.println(""); }); //ok - resolves to call(SAM2)
         call(x -> { return (Object) null; }); //error - call(SAM3) is not applicable because of cyclic inference
         call(x -> { return null; }); ////ok - resolves to call(SAM1)
--- a/langtools/test/tools/javac/lambda/TargetType21.out	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TargetType21.out	Wed Jan 16 11:58:15 2013 -0800
@@ -1,3 +1,3 @@
 TargetType21.java:28:9: compiler.err.ref.ambiguous: call, kindname.method, call(TargetType21.SAM1), TargetType21, kindname.method, call(TargetType21.SAM2), TargetType21
-TargetType21.java:30:9: compiler.err.cant.apply.symbols: kindname.method, call, @755,{(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, <R,A>call(TargetType21.SAM3<R,A>), (compiler.misc.cyclic.inference: A))}
+TargetType21.java:30:9: compiler.err.cant.apply.symbols: kindname.method, call, @737,{(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, call(TargetType21.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val)))),(compiler.misc.inapplicable.method: kindname.method, TargetType21, <R,A>call(TargetType21.SAM3<R,A>), (compiler.misc.cyclic.inference: A))}
 2 errors
--- a/langtools/test/tools/javac/lambda/TestInvokeDynamic.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/TestInvokeDynamic.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,9 @@
  * @bug 8003280
  * @summary Add lambda tests
  *  Add back-end support for invokedynamic
- *
+ * @library ../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main TestInvokeDynamic
  */
 
 import com.sun.source.tree.MethodInvocationTree;
@@ -66,7 +68,6 @@
 
 import javax.tools.Diagnostic;
 import javax.tools.JavaCompiler;
-import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
 import javax.tools.StandardJavaFileManager;
@@ -74,69 +75,80 @@
 
 import static com.sun.tools.javac.jvm.ClassFile.*;
 
-public class TestInvokeDynamic {
-
-    static int checkCount = 0;
+public class TestInvokeDynamic
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum StaticArgumentKind {
         STRING("Hello!", "String", "Ljava/lang/String;") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_String_info) &&
-                        ((CONSTANT_String_info)cpInfo).getString().equals(value);
+                        ((CONSTANT_String_info)cpInfo).getString()
+                        .equals(value);
             }
         },
         CLASS(null, "Class<?>", "Ljava/lang/Class;") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Class_info) &&
-                        ((CONSTANT_Class_info)cpInfo).getName().equals("java/lang/String");
+                        ((CONSTANT_Class_info)cpInfo).getName()
+                        .equals("java/lang/String");
             }
         },
         INTEGER(1, "int", "I") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Integer_info) &&
-                        ((CONSTANT_Integer_info)cpInfo).value == ((Integer)value).intValue();
+                        ((CONSTANT_Integer_info)cpInfo).value ==
+                        ((Integer)value).intValue();
             }
         },
         LONG(1L, "long", "J") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Long_info) &&
-                        ((CONSTANT_Long_info)cpInfo).value == ((Long)value).longValue();
+                        ((CONSTANT_Long_info)cpInfo).value ==
+                        ((Long)value).longValue();
             }
         },
         FLOAT(1.0f, "float", "F") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Float_info) &&
-                        ((CONSTANT_Float_info)cpInfo).value == ((Float)value).floatValue();
+                        ((CONSTANT_Float_info)cpInfo).value ==
+                        ((Float)value).floatValue();
             }
         },
         DOUBLE(1.0, "double","D") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_Double_info) &&
-                        ((CONSTANT_Double_info)cpInfo).value == ((Double)value).doubleValue();
+                        ((CONSTANT_Double_info)cpInfo).value ==
+                        ((Double)value).doubleValue();
             }
         },
         METHOD_HANDLE(null, "MethodHandle", "Ljava/lang/invoke/MethodHandle;") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
-                if (!(cpInfo instanceof CONSTANT_MethodHandle_info)) return false;
-                CONSTANT_MethodHandle_info handleInfo = (CONSTANT_MethodHandle_info)cpInfo;
+                if (!(cpInfo instanceof CONSTANT_MethodHandle_info))
+                    return false;
+                CONSTANT_MethodHandle_info handleInfo =
+                        (CONSTANT_MethodHandle_info)cpInfo;
                 return handleInfo.getCPRefInfo().getClassName().equals("Array") &&
                         handleInfo.reference_kind == RefKind.REF_invokeVirtual &&
-                        handleInfo.getCPRefInfo().getNameAndTypeInfo().getName().equals("clone") &&
-                        handleInfo.getCPRefInfo().getNameAndTypeInfo().getType().equals("()Ljava/lang/Object;");
+                        handleInfo.getCPRefInfo()
+                        .getNameAndTypeInfo().getName().equals("clone") &&
+                        handleInfo.getCPRefInfo()
+                        .getNameAndTypeInfo().getType().equals("()Ljava/lang/Object;");
             }
         },
         METHOD_TYPE(null, "MethodType", "Ljava/lang/invoke/MethodType;") {
             @Override
             boolean check(CPInfo cpInfo) throws Exception {
                 return (cpInfo instanceof CONSTANT_MethodType_info) &&
-                        ((CONSTANT_MethodType_info)cpInfo).getType().equals("()Ljava/lang/Object;");
+                        ((CONSTANT_MethodType_info)cpInfo).getType()
+                        .equals("()Ljava/lang/Object;");
             }
         };
 
@@ -144,7 +156,8 @@
         String sourceTypeStr;
         String bytecodeTypeStr;
 
-        StaticArgumentKind(Object value, String sourceTypeStr, String bytecodeTypeStr) {
+        StaticArgumentKind(Object value, String sourceTypeStr,
+                String bytecodeTypeStr) {
             this.value = value;
             this.sourceTypeStr = sourceTypeStr;
             this.bytecodeTypeStr = bytecodeTypeStr;
@@ -163,7 +176,8 @@
                 case CLASS:
                     return syms.stringType.tsym;
                 case METHOD_HANDLE:
-                    return new Pool.MethodHandle(REF_invokeVirtual, syms.arrayCloneMethod, types);
+                    return new Pool.MethodHandle(REF_invokeVirtual,
+                            syms.arrayCloneMethod, types);
                 case METHOD_TYPE:
                     return syms.arrayCloneMethod.type;
                 default:
@@ -186,23 +200,21 @@
     }
 
     public static void main(String... args) throws Exception {
-        // Create a single file manager and compiler and reuse it for each compile to save time.
-        StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
-        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
         for (StaticArgumentsArity arity : StaticArgumentsArity.values()) {
             if (arity.arity == 0) {
-                new TestInvokeDynamic(arity).compileAndCheck(fm, tool);
+                pool.execute(new TestInvokeDynamic(arity));
             } else {
                 for (StaticArgumentKind sak1 : StaticArgumentKind.values()) {
                     if (arity.arity == 1) {
-                        new TestInvokeDynamic(arity, sak1).compileAndCheck(fm, tool);
+                        pool.execute(new TestInvokeDynamic(arity, sak1));
                     } else {
                         for (StaticArgumentKind sak2 : StaticArgumentKind.values()) {
                             if (arity.arity == 2) {
-                                new TestInvokeDynamic(arity, sak1, sak2).compileAndCheck(fm, tool);
+                                pool.execute(new TestInvokeDynamic(arity, sak1, sak2));
                             } else {
                                 for (StaticArgumentKind sak3 : StaticArgumentKind.values()) {
-                                    new TestInvokeDynamic(arity, sak1, sak2, sak3).compileAndCheck(fm, tool);
+                                    pool.execute(
+                                        new TestInvokeDynamic(arity, sak1, sak2, sak3));
                                 }
                             }
                         }
@@ -211,23 +223,23 @@
             }
         }
 
-        System.out.println("Total checks made: " + checkCount);
+        checkAfterExec();
     }
 
     StaticArgumentsArity arity;
     StaticArgumentKind[] saks;
-    JavaSource source;
     DiagChecker dc;
 
     TestInvokeDynamic(StaticArgumentsArity arity, StaticArgumentKind... saks) {
         this.arity = arity;
         this.saks = saks;
-        source = new JavaSource();
         dc = new DiagChecker();
     }
 
-    void compileAndCheck(JavaFileManager fm, JavaCompiler tool) throws Exception {
-        JavacTaskImpl ct = (JavacTaskImpl)tool.getTask(null, fm, dc,
+    public void run() {
+        int id = checkCount.incrementAndGet();
+        JavaSource source = new JavaSource(id);
+        JavacTaskImpl ct = (JavacTaskImpl)comp.getTask(null, fm.get(), dc,
                 null, null, Arrays.asList(source));
         Context context = ct.getContext();
         Symtab syms = Symtab.instance(context);
@@ -238,16 +250,20 @@
             ct.generate();
         } catch (Throwable t) {
             t.printStackTrace();
-            throw new AssertionError(String.format("Error thrown when compiling following code\n%s", source.source));
+            throw new AssertionError(
+                    String.format("Error thrown when compiling following code\n%s",
+                    source.source));
         }
         if (dc.diagFound) {
-            throw new AssertionError(String.format("Diags found when compiling following code\n%s\n\n%s", source.source, dc.printDiags()));
+            throw new AssertionError(
+                    String.format("Diags found when compiling following code\n%s\n\n%s",
+                    source.source, dc.printDiags()));
         }
-        verifyBytecode();
+        verifyBytecode(id);
     }
 
-    void verifyBytecode() {
-        File compiledTest = new File("Test.class");
+    void verifyBytecode(int id) {
+        File compiledTest = new File(String.format("Test%d.class", id));
         try {
             ClassFile cf = ClassFile.read(compiledTest);
             Method testMethod = null;
@@ -260,7 +276,8 @@
             if (testMethod == null) {
                 throw new Error("Test method not found");
             }
-            Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
+            Code_attribute ea =
+                    (Code_attribute)testMethod.attributes.get(Attribute.Code);
             if (testMethod == null) {
                 throw new Error("Code attribute for test() method not found");
             }
@@ -270,10 +287,12 @@
             for (Instruction i : ea.getInstructions()) {
                 if (i.getMnemonic().equals("invokedynamic")) {
                     CONSTANT_InvokeDynamic_info indyInfo =
-                            (CONSTANT_InvokeDynamic_info)cf.constant_pool.get(i.getShort(1));
+                         (CONSTANT_InvokeDynamic_info)cf
+                            .constant_pool.get(i.getShort(1));
                     bsmIdx = indyInfo.bootstrap_method_attr_index;
                     if (!indyInfo.getNameAndTypeInfo().getType().equals("()V")) {
-                        throw new AssertionError("type mismatch for CONSTANT_InvokeDynamic_info");
+                        throw new
+                            AssertionError("type mismatch for CONSTANT_InvokeDynamic_info");
                     }
                 }
             }
@@ -281,34 +300,41 @@
                 throw new Error("Missing invokedynamic in generated code");
             }
 
-            BootstrapMethods_attribute bsm_attr = (BootstrapMethods_attribute)cf.getAttribute(Attribute.BootstrapMethods);
+            BootstrapMethods_attribute bsm_attr =
+                    (BootstrapMethods_attribute)cf
+                    .getAttribute(Attribute.BootstrapMethods);
             if (bsm_attr.bootstrap_method_specifiers.length != 1) {
-                throw new Error("Bad number of method specifiers in BootstrapMethods attribute");
+                throw new Error("Bad number of method specifiers " +
+                        "in BootstrapMethods attribute");
             }
             BootstrapMethods_attribute.BootstrapMethodSpecifier bsm_spec =
                     bsm_attr.bootstrap_method_specifiers[0];
 
             if (bsm_spec.bootstrap_arguments.length != arity.arity) {
-                throw new Error("Bad number of static invokedynamic args in BootstrapMethod attribute");
+                throw new Error("Bad number of static invokedynamic args " +
+                        "in BootstrapMethod attribute");
             }
 
             int count = 0;
             for (StaticArgumentKind sak : saks) {
-                if (!sak.check(cf.constant_pool.get(bsm_spec.bootstrap_arguments[count]))) {
+                if (!sak.check(cf.constant_pool
+                        .get(bsm_spec.bootstrap_arguments[count]))) {
                     throw new Error("Bad static argument value " + sak);
                 }
                 count++;
             }
 
             CONSTANT_MethodHandle_info bsm_handle =
-                    (CONSTANT_MethodHandle_info)cf.constant_pool.get(bsm_spec.bootstrap_method_ref);
+                    (CONSTANT_MethodHandle_info)cf.constant_pool
+                    .get(bsm_spec.bootstrap_method_ref);
 
             if (bsm_handle.reference_kind != RefKind.REF_invokeStatic) {
                 throw new Error("Bad kind on boostrap method handle");
             }
 
             CONSTANT_Methodref_info bsm_ref =
-                    (CONSTANT_Methodref_info)cf.constant_pool.get(bsm_handle.reference_index);
+                    (CONSTANT_Methodref_info)cf.constant_pool
+                    .get(bsm_handle.reference_index);
 
             if (!bsm_ref.getClassInfo().getName().equals("Bootstrap")) {
                 throw new Error("Bad owner of boostrap method");
@@ -318,8 +344,11 @@
                 throw new Error("Bad boostrap method name");
             }
 
-            if (!bsm_ref.getNameAndTypeInfo().getType().equals(asBSMSignatureString())) {
-                throw new Error("Bad boostrap method type" + bsm_ref.getNameAndTypeInfo().getType() + " " + asBSMSignatureString());
+            if (!bsm_ref.getNameAndTypeInfo()
+                    .getType().equals(asBSMSignatureString())) {
+                throw new Error("Bad boostrap method type" +
+                        bsm_ref.getNameAndTypeInfo().getType() + " " +
+                        asBSMSignatureString());
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -341,20 +370,22 @@
 
         static final String source_template = "import java.lang.invoke.*;\n" +
                 "class Bootstrap {\n" +
-                "   public static CallSite bsm(MethodHandles.Lookup lookup, String name, MethodType methodType #SARGS) {\n" +
+                "   public static CallSite bsm(MethodHandles.Lookup lookup, " +
+                "String name, MethodType methodType #SARGS) {\n" +
                 "       return null;\n" +
                 "   }\n" +
                 "}\n" +
-                "class Test {\n" +
+                "class Test#ID {\n" +
                 "   void m() { }\n" +
                 "   void test() { m(); }\n" +
                 "}";
 
         String source;
 
-        JavaSource() {
+        JavaSource(int id) {
             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
-            source = source_template.replace("#SARGS", asSignatureString());
+            source = source_template.replace("#SARGS", asSignatureString())
+                    .replace("#ID", String.valueOf(id));
         }
 
         @Override
@@ -411,7 +442,8 @@
                 for (int i = 0; i < arity.arity ; i++) {
                     staticArgs[i] = saks[i].getValue(syms, names, types);
                 }
-                ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs);
+                ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name,
+                        oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs);
             }
             return null;
         }
@@ -426,7 +458,8 @@
         }
     }
 
-    static class DiagChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean diagFound;
         ArrayList<String> diags = new ArrayList<>();
@@ -445,4 +478,5 @@
             return buf.toString();
         }
     }
+
 }
--- a/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,24 +26,23 @@
  * @bug 8003280
  * @summary Add lambda tests
  *  Automatic test for checking correctness of structural most specific test routine
- * @run main/timeout=360 StructuralMostSpecificTest
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main/timeout=600 StructuralMostSpecificTest
  */
 
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.ClientCodeWrapper;
-import com.sun.tools.javac.util.JCDiagnostic;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.ClientCodeWrapper;
+import com.sun.tools.javac.util.JCDiagnostic;
 
-public class StructuralMostSpecificTest {
-
-    static int checkCount = 0;
+public class StructuralMostSpecificTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum RetTypeKind {
         SHORT("short"),
@@ -105,7 +104,7 @@
         VOID("return;"),
         SHORT("return (short)0;"),
         INT("return 0;"),
-        INTEGER("return (Integer)null"),
+        INTEGER("return (Integer)null;"),
         NULL("return null;");
 
         String retStr;
@@ -142,11 +141,6 @@
     }
 
     public static void main(String... args) throws Exception {
-
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (LambdaReturnKind lrk : LambdaReturnKind.values()) {
             for (RetTypeKind rk1 : RetTypeKind.values()) {
                 for (RetTypeKind rk2 : RetTypeKind.values()) {
@@ -154,7 +148,9 @@
                         for (ExceptionKind ek2 : ExceptionKind.values()) {
                             for (ArgTypeKind ak11 : ArgTypeKind.values()) {
                                 for (ArgTypeKind ak12 : ArgTypeKind.values()) {
-                                    new StructuralMostSpecificTest(lrk, rk1, rk2, ek1, ek2, ak11, ak12).run(comp, fm);
+                                    pool.execute(
+                                        new StructuralMostSpecificTest(lrk, rk1,
+                                            rk2, ek1, ek2, ak11, ak12));
                                 }
                             }
                         }
@@ -162,7 +158,8 @@
                 }
             }
         }
-        System.out.println("Total check executed: " + checkCount);
+
+        checkAfterExec();
     }
 
     LambdaReturnKind lrk;
@@ -218,20 +215,22 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+    public void run() {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
                 Arrays.asList("-XDverboseResolution=all,-predef,-internal,-object-init"),
                 null, Arrays.asList(source));
         try {
             ct.analyze();
         } catch (Throwable ex) {
-            throw new AssertionError("Error thron when analyzing the following source:\n" + source.getCharContent(true));
+            throw new
+                AssertionError("Error thron when analyzing the following source:\n" +
+                    source.getCharContent(true));
         }
         check();
     }
 
     void check() {
-        checkCount++;
+        checkCount.incrementAndGet();
 
         if (!lrk.compatibleWith(rt1) || !lrk.compatibleWith(rt2))
             return;
@@ -265,8 +264,8 @@
         }
     }
 
-    boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1, ExceptionKind ek2,
-            ArgTypeKind ak1, ArgTypeKind ak2) {
+    boolean moreSpecific(RetTypeKind rk1, RetTypeKind rk2, ExceptionKind ek1,
+            ExceptionKind ek2, ArgTypeKind ak1, ArgTypeKind ak2) {
         if (!rk1.moreSpecificThan(rk2))
             return false;
 
@@ -276,7 +275,8 @@
         return true;
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean ambiguityFound;
         String mostSpecificSig;
@@ -287,12 +287,16 @@
                         diagnostic.getCode().equals("compiler.err.ref.ambiguous")) {
                     ambiguityFound = true;
                 } else if (diagnostic.getKind() == Diagnostic.Kind.NOTE &&
-                        diagnostic.getCode().equals("compiler.note.verbose.resolve.multi")) {
+                        diagnostic.getCode()
+                        .equals("compiler.note.verbose.resolve.multi")) {
                     ClientCodeWrapper.DiagnosticSourceUnwrapper dsu =
-                            (ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
-                    JCDiagnostic.MultilineDiagnostic mdiag = (JCDiagnostic.MultilineDiagnostic)dsu.d;
+                        (ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
+                    JCDiagnostic.MultilineDiagnostic mdiag =
+                        (JCDiagnostic.MultilineDiagnostic)dsu.d;
                     int mostSpecificIndex = (Integer)mdiag.getArgs()[2];
-                    mostSpecificSig = ((JCDiagnostic)mdiag.getSubdiagnostics().get(mostSpecificIndex)).getArgs()[1].toString();
+                    mostSpecificSig =
+                        ((JCDiagnostic)mdiag.getSubdiagnostics()
+                            .get(mostSpecificIndex)).getArgs()[1].toString();
                 }
             } catch (RuntimeException t) {
                 t.printStackTrace();
@@ -300,4 +304,5 @@
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/lambda/typeInference/combo/TypeInferenceComboTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,22 +25,24 @@
  * @test
  * @bug 8003280
  * @summary Add lambda tests
- *  perform automated checks in type inference in lambda expressions in different contexts
+ *  perform automated checks in type inference in lambda expressions
+ *  in different contexts
+ * @library ../../../lib
+ * @build JavacTestingAbstractThreadedTest
  * @compile  TypeInferenceComboTest.java
  * @run main/timeout=360 TypeInferenceComboTest
  */
 
-import com.sun.source.util.JavacTask;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.ToolProvider;
-import javax.tools.StandardJavaFileManager;
+import com.sun.source.util.JavacTask;
 
-public class TypeInferenceComboTest {
+public class TypeInferenceComboTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
     enum Context {
         ASSIGNMENT("SAM#Type s = #LBody;"),
         METHOD_CALL("#GenericDeclKind void method1(SAM#Type s) { }\n" +
@@ -59,27 +61,35 @@
             this.context = context;
         }
 
-        String getContext(SamKind sk, TypeKind samTargetT, Keyword kw, TypeKind parameterT, TypeKind returnT, LambdaKind lk, ParameterKind pk, GenericDeclKind gdk, LambdaBody lb) {
+        String getContext(SamKind sk, TypeKind samTargetT, Keyword kw,
+                TypeKind parameterT, TypeKind returnT, LambdaKind lk,
+                ParameterKind pk, GenericDeclKind gdk, LambdaBody lb) {
             String result = context;
             if (sk == SamKind.GENERIC) {
                 if(this == Context.METHOD_CALL) {
-                    result = result.replaceAll("#GenericDeclKind", gdk.getGenericDeclKind(samTargetT));
+                    result = result.replaceAll("#GenericDeclKind",
+                            gdk.getGenericDeclKind(samTargetT));
                     if(gdk == GenericDeclKind.NON_GENERIC)
-                        result = result.replaceAll("#Type", "<" + samTargetT.typeStr + ">");
+                        result = result.replaceAll("#Type", "<" +
+                                samTargetT.typeStr + ">");
                     else //#GenericDeclKind is <T> or <T extends xxx>
                         result = result.replaceAll("#Type", "<T>");
                 }
                 else {
                     if(kw == Keyword.VOID)
-                        result = result.replaceAll("#Type", "<" + samTargetT.typeStr + ">");
+                        result = result.replaceAll("#Type", "<" +
+                                samTargetT.typeStr + ">");
                     else
-                        result = result.replaceAll("#Type", "<? " + kw.keyStr + " " + samTargetT.typeStr + ">");
+                        result = result.replaceAll("#Type", "<? " + kw.keyStr +
+                                " " + samTargetT.typeStr + ">");
                 }
             }
             else
-                result = result.replaceAll("#Type", "").replaceAll("#GenericDeclKind", "");
+                result = result.replaceAll("#Type", "").
+                        replaceAll("#GenericDeclKind", "");
 
-            return result.replaceAll("#LBody", lb.getLambdaBody(samTargetT, parameterT, returnT, lk, pk));
+            return result.replaceAll("#LBody",
+                    lb.getLambdaBody(samTargetT, parameterT, returnT, lk, pk));
         }
     }
 
@@ -94,8 +104,10 @@
         }
 
         String getSam(TypeKind parameterT, TypeKind returnT) {
-            return sam_str.replaceAll("#ARG", parameterT == TypeKind.VOID ? "" : parameterT.typeStr + " arg")
-                          .replaceAll("#R", returnT.typeStr);
+            return sam_str.replaceAll("#ARG",
+                    parameterT == TypeKind.VOID ?
+                        "" : parameterT.typeStr + " arg")
+                    .replaceAll("#R", returnT.typeStr);
         }
     }
 
@@ -104,7 +116,8 @@
         STRING("String", "\"hello\""),
         INTEGER("Integer", "1"),
         INT("int", "0"),
-        COMPARATOR("java.util.Comparator<String>", "(java.util.Comparator<String>)(a, b) -> a.length()-b.length()"),
+        COMPARATOR("java.util.Comparator<String>",
+                "(java.util.Comparator<String>)(a, b) -> a.length()-b.length()"),
         SAM("SAM2", "null"),
         GENERIC("T", null);
 
@@ -152,8 +165,10 @@
     }
 
     enum LambdaBody {
-        RETURN_VOID("() -> #RET"),//no parameters, return type is one of the TypeKind
-        RETURN_ARG("(#PK arg) -> #RET");//has parameters, return type is one of the TypeKind
+        //no parameters, return type is one of the TypeKind
+        RETURN_VOID("() -> #RET"),
+        //has parameters, return type is one of the TypeKind
+        RETURN_ARG("(#PK arg) -> #RET");
 
         String bodyStr;
 
@@ -161,12 +176,14 @@
             this.bodyStr = bodyStr;
         }
 
-        String getLambdaBody(TypeKind samTargetT, TypeKind parameterT, TypeKind returnT, LambdaKind lk, ParameterKind pk) {
+        String getLambdaBody(TypeKind samTargetT, TypeKind parameterT,
+                TypeKind returnT, LambdaKind lk, ParameterKind pk) {
             String result = bodyStr.replaceAll("#PK", pk.paramTemplate);
 
             if(result.contains("#TYPE")) {
                 if (parameterT == TypeKind.GENERIC && this != RETURN_VOID)
-                    result = result.replaceAll("#TYPE", samTargetT == null? "": samTargetT.typeStr);
+                    result = result.replaceAll("#TYPE",
+                            samTargetT == null? "": samTargetT.typeStr);
                 else
                     result = result.replaceAll("#TYPE", parameterT.typeStr);
             }
@@ -174,9 +191,12 @@
                 return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", "arg"));
             else {
                 if(returnT != TypeKind.GENERIC)
-                    return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", (returnT==TypeKind.VOID && lk==LambdaKind.EXPRESSION)? "{}" : returnT.valStr));
+                    return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL",
+                            (returnT==TypeKind.VOID &&
+                            lk==LambdaKind.EXPRESSION) ? "{}" : returnT.valStr));
                 else
-                    return result.replaceAll("#RET", lk.stmt.replaceAll("#VAL", samTargetT.valStr));
+                    return result.replaceAll("#RET",
+                            lk.stmt.replaceAll("#VAL", samTargetT.valStr));
             }
         }
     }
@@ -203,8 +223,10 @@
         }
         else if (lambdaBodyType != LambdaBody.RETURN_ARG)
             return false;
-        if (  genericDeclKind == GenericDeclKind.GENERIC_NOBOUND || genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
-            if ( parameterType == TypeKind.GENERIC && parameterKind == ParameterKind.IMPLICIT) //cyclic inference
+        if (  genericDeclKind == GenericDeclKind.GENERIC_NOBOUND ||
+                genericDeclKind == GenericDeclKind.GENERIC_BOUND ) {
+            if ( parameterType == TypeKind.GENERIC &&
+                    parameterKind == ParameterKind.IMPLICIT) //cyclic inference
                 return false;
         }
         return true;
@@ -216,7 +238,8 @@
                          "}\n";
     SourceFile samSourceFile = new SourceFile("Sam.java", templateStr) {
         public String toString() {
-            return template.replaceAll("#C", samKind.getSam(parameterType, returnType));
+            return template.replaceAll("#C",
+                    samKind.getSam(parameterType, returnType));
         }
     };
 
@@ -225,22 +248,35 @@
                                                  "    #Context\n" +
                                                  "}") {
         public String toString() {
-            return template.replaceAll("#Context", context.getContext(samKind, samTargetType, keyword, parameterType, returnType, lambdaKind, parameterKind, genericDeclKind, lambdaBodyType));
+            return template.replaceAll("#Context",
+                    context.getContext(samKind, samTargetType, keyword,
+                    parameterType, returnType, lambdaKind, parameterKind,
+                    genericDeclKind, lambdaBodyType));
         }
     };
 
-    void test() throws Exception {
-        System.out.println("kk:");
+    public void run() {
+        outWriter.println("kk:");
         StringBuilder sb = new StringBuilder("SamKind:");
-        sb.append(samKind).append(" SamTargetType:").append(samTargetType).append(" ParameterType:").append(parameterType)
-            .append(" ReturnType:").append(returnType).append(" Context:").append(context).append(" LambdaKind:").append(lambdaKind)
-            .append(" LambdaBodyType:").append(lambdaBodyType).append(" ParameterKind:").append(parameterKind).append(" Keyword:").append(keyword);
-        System.out.println(sb);
+        sb.append(samKind).append(" SamTargetType:")
+            .append(samTargetType).append(" ParameterType:").append(parameterType)
+            .append(" ReturnType:").append(returnType).append(" Context:")
+            .append(context).append(" LambdaKind:").append(lambdaKind)
+            .append(" LambdaBodyType:").append(lambdaBodyType)
+            .append(" ParameterKind:").append(parameterKind).append(" Keyword:")
+            .append(keyword);
+        outWriter.println(sb);
         DiagnosticChecker dc = new DiagnosticChecker();
-        JavacTask ct = (JavacTask)comp.getTask(null, fm, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile));
-        ct.analyze();
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), dc,
+                null, null, Arrays.asList(samSourceFile, clientSourceFile));
+        try {
+            ct.analyze();
+        } catch (Throwable t) {
+            processException(t);
+        }
         if (dc.errorFound == checkTypeInference()) {
-            throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile + "\n" + parameterType + " " + returnType);
+            throw new AssertionError(samSourceFile + "\n\n" +
+                    clientSourceFile + "\n" + parameterType + " " + returnType);
         }
     }
 
@@ -261,7 +297,8 @@
         public abstract String toString();
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound = false;
 
@@ -283,10 +320,9 @@
     Keyword keyword;
     GenericDeclKind genericDeclKind;
 
-    static JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-    static StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
-    TypeInferenceComboTest(SamKind sk, TypeKind samTargetT, TypeKind parameterT, TypeKind returnT, LambdaBody lb, Context c, LambdaKind lk, ParameterKind pk, Keyword kw, GenericDeclKind gdk) {
+    TypeInferenceComboTest(SamKind sk, TypeKind samTargetT, TypeKind parameterT,
+            TypeKind returnT, LambdaBody lb, Context c, LambdaKind lk,
+            ParameterKind pk, Keyword kw, GenericDeclKind gdk) {
         samKind = sk;
         samTargetType = samTargetT;
         parameterType = parameterT;
@@ -308,24 +344,14 @@
                             for(LambdaKind lambdaK : LambdaKind.values()) {
                                 for (SamKind sk : SamKind.values()) {
                                     if (sk == SamKind.NON_GENERIC) {
-                                        if(parameterT != TypeKind.GENERIC && returnT != TypeKind.GENERIC )
-                                            new TypeInferenceComboTest(sk, null, parameterT, returnT, lb, ct, lambdaK, parameterK, null, null).test();
+                                        generateNonGenericSAM(ct, returnT,
+                                                parameterT, lb, parameterK,
+                                                lambdaK, sk);
                                     }
                                     else if (sk == SamKind.GENERIC) {
-                                        for (Keyword kw : Keyword.values()) {
-                                            for (TypeKind samTargetT : TypeKind.values()) {
-                                                if(samTargetT != TypeKind.VOID && samTargetT != TypeKind.INT && samTargetT != TypeKind.GENERIC
-                                                   && (parameterT == TypeKind.GENERIC || returnT == TypeKind.GENERIC)) {
-                                                    if(ct != Context.METHOD_CALL) {
-                                                        new TypeInferenceComboTest(sk, samTargetT, parameterT, returnT, lb, ct, lambdaK, parameterK, kw, null).test();
-                                                    }
-                                                    else {//Context.METHOD_CALL
-                                                        for (GenericDeclKind gdk : GenericDeclKind.values())
-                                                            new TypeInferenceComboTest(sk, samTargetT, parameterT, returnT, lb, ct, lambdaK, parameterK, kw, gdk).test();
-                                                    }
-                                                }
-                                            }
-                                        }
+                                        generateGenericSAM(ct, returnT,
+                                                parameterT, lb, parameterK,
+                                                lambdaK, sk);
                                     }
                                 }
                             }
@@ -334,5 +360,44 @@
                 }
             }
         }
+
+        checkAfterExec(false);
     }
+
+    static void generateNonGenericSAM(Context ct, TypeKind returnT,
+            TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
+            LambdaKind lambdaK, SamKind sk) {
+        if(parameterT != TypeKind.GENERIC && returnT != TypeKind.GENERIC ) {
+            pool.execute(new TypeInferenceComboTest(sk, null, parameterT,
+                    returnT, lb, ct, lambdaK, parameterK, null, null));
+        }
+    }
+
+    static void generateGenericSAM(Context ct, TypeKind returnT,
+            TypeKind parameterT, LambdaBody lb, ParameterKind parameterK,
+            LambdaKind lambdaK, SamKind sk) {
+        for (Keyword kw : Keyword.values()) {
+            for (TypeKind samTargetT : TypeKind.values()) {
+                if(samTargetT != TypeKind.VOID &&
+                   samTargetT != TypeKind.INT &&
+                   samTargetT != TypeKind.GENERIC &&
+                   (parameterT == TypeKind.GENERIC ||
+                   returnT == TypeKind.GENERIC)) {
+                    if(ct != Context.METHOD_CALL) {
+                        pool.execute(
+                            new TypeInferenceComboTest(sk, samTargetT, parameterT,
+                                returnT, lb, ct, lambdaK, parameterK, kw, null));
+                    } else {//Context.METHOD_CALL
+                        for (GenericDeclKind gdk :
+                                GenericDeclKind.values())
+                            pool.execute(
+                                    new TypeInferenceComboTest(sk, samTargetT,
+                                    parameterT, returnT, lb, ct, lambdaK,
+                                    parameterK, kw, gdk));
+                    }
+                }
+            }
+         }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lib/JavacTestingAbstractThreadedTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.tools.JavaCompiler;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * An abstract superclass for threaded tests.
+ *
+ * This class will try to read a property named test.concurrency.
+ * The property can be provided by passing this option to jtreg:
+ * -javaoption:-Dtest.concurrency=#
+ *
+ * If the property is not set the class will use a heuristic to determine the
+ * maximum number of threads that can be fired to execute a given test.
+ */
+public abstract class JavacTestingAbstractThreadedTest {
+
+    protected static int getThreadPoolSize() {
+        Integer testConc = Integer.getInteger("test.concurrency");
+        if (testConc != null) return testConc;
+        int cores = Runtime.getRuntime().availableProcessors();
+        return Math.max(2, Math.min(8, cores / 2));
+    }
+
+    protected static void checkAfterExec() throws InterruptedException {
+        checkAfterExec(true);
+    };
+
+    protected static boolean throwAssertionOnError = true;
+
+    protected static boolean printAll = false;
+
+    protected static StringWriter errSWriter = new StringWriter();
+    protected static PrintWriter errWriter = new PrintWriter(errSWriter);
+
+    protected static StringWriter outSWriter = new StringWriter();
+    protected static PrintWriter outWriter = new PrintWriter(outSWriter);
+
+    protected static void checkAfterExec(boolean printCheckCount)
+            throws InterruptedException {
+        pool.shutdown();
+        while (!pool.isTerminated()) {
+            Thread.sleep(10);
+        }
+        if (errCount.get() > 0) {
+            if (throwAssertionOnError) {
+                closePrinters();
+                System.err.println(errSWriter.toString());
+                throw new AssertionError(
+                    String.format("%d errors found", errCount.get()));
+            } else {
+                System.err.println(
+                        String.format("%d errors found", errCount.get()));
+            }
+        } else if (printCheckCount) {
+            outWriter.println("Total check executed: " + checkCount.get());
+        }
+        closePrinters();
+        if (printAll) {
+            System.out.println(errSWriter.toString());
+            System.out.println(outSWriter.toString());
+        }
+    }
+
+    protected static void closePrinters() {
+        errWriter.close();
+        outWriter.close();
+    }
+
+    protected static void processException(Throwable t) {
+        errCount.incrementAndGet();
+        t.printStackTrace(errWriter);
+        pool.shutdown();
+    }
+
+    //number of checks executed
+    protected static AtomicInteger checkCount = new AtomicInteger();
+
+    //number of errors found while running combo tests
+    protected static AtomicInteger errCount = new AtomicInteger();
+
+    //create default shared JavaCompiler - reused across multiple compilations
+    protected static JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+
+    protected static ExecutorService pool = Executors.newFixedThreadPool(
+            getThreadPoolSize(), new ThreadFactory() {
+        @Override
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(r);
+            t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
+                @Override
+                public void uncaughtException(Thread t, Throwable e) {
+                    pool.shutdown();
+                    errCount.incrementAndGet();
+                    e.printStackTrace(System.err);
+                }
+            });
+            return t;
+        }
+    });
+
+    /*
+     * File manager is not thread-safe so it cannot be re-used across multiple
+     * threads. However we cache per-thread FileManager to avoid excessive
+     * object creation
+     */
+    protected static final ThreadLocal<StandardJavaFileManager> fm =
+        new ThreadLocal<StandardJavaFileManager>() {
+            @Override protected StandardJavaFileManager initialValue() {
+                return comp.getStandardFileManager(null, null, null);
+            }
+        };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/main/Option_J_At_Test.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,70 @@
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006037
+ * @summary extra space in javac -help for -J and @ options
+ */
+
+public class Option_J_At_Test {
+    public static void main(String... args) throws Exception {
+        new Option_J_At_Test().run();
+    }
+
+    void run() throws Exception {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        String[] help = { "-help" };
+        int rc = com.sun.tools.javac.Main.compile(help, pw);
+        pw.flush();
+        String out = sw.toString();
+        System.out.println(out);
+        check(out, "-J<flag>",     true);
+        check(out, "-J <flag>",    false);
+        check(out, "@<filename>",  true);
+        check(out, "@ <filename>", false);
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+    }
+
+    void check(String out, String text, boolean expect) {
+        if (out.contains(text) != expect) {
+            if (expect)
+                error("expected string not found: " + text);
+            else
+                error("unexpected string found: " + text);
+        }
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+}
--- a/langtools/test/tools/javac/multicatch/7030606/DisjunctiveTypeWellFormednessTest.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/multicatch/7030606/DisjunctiveTypeWellFormednessTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,19 +25,21 @@
  * @test
  * @bug 7030606
  * @summary Project-coin: multi-catch types should be pairwise disjoint
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main DisjunctiveTypeWellFormednessTest
  */
 
-import com.sun.source.util.JavacTask;
 import java.net.URI;
 import java.util.Arrays;
 import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
 
-public class DisjunctiveTypeWellFormednessTest {
+public class DisjunctiveTypeWellFormednessTest
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum Alternative {
         EXCEPTION("Exception"),
@@ -92,40 +94,37 @@
     }
 
     public static void main(String... args) throws Exception {
-
-        //create default shared JavaCompiler - reused across multiple compilations
-        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
-        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
-
         for (Arity arity : Arity.values()) {
             for (Alternative a1 : Alternative.values()) {
                 if (arity == Arity.ONE) {
-                    new DisjunctiveTypeWellFormednessTest(a1).run(comp, fm);
+                    pool.execute(new DisjunctiveTypeWellFormednessTest(a1));
                     continue;
                 }
                 for (Alternative a2 : Alternative.values()) {
                     if (arity == Arity.TWO) {
-                        new DisjunctiveTypeWellFormednessTest(a1, a2).run(comp, fm);
+                        pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2));
                         continue;
                     }
                     for (Alternative a3 : Alternative.values()) {
                         if (arity == Arity.THREE) {
-                            new DisjunctiveTypeWellFormednessTest(a1, a2, a3).run(comp, fm);
+                            pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3));
                             continue;
                         }
                         for (Alternative a4 : Alternative.values()) {
                             if (arity == Arity.FOUR) {
-                                new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4).run(comp, fm);
+                                pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4));
                                 continue;
                             }
                             for (Alternative a5 : Alternative.values()) {
-                                new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4, a5).run(comp, fm);
+                                pool.execute(new DisjunctiveTypeWellFormednessTest(a1, a2, a3, a4, a5));
                             }
                         }
                     }
                 }
             }
         }
+
+        checkAfterExec(false);
     }
 
     Alternative[] alternatives;
@@ -159,10 +158,16 @@
         }
     }
 
-    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+    @Override
+    public void run() {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
                 null, null, Arrays.asList(source));
-        ct.analyze();
+        try {
+            ct.analyze();
+        } catch (Throwable t) {
+            processException(t);
+            return;
+        }
         check();
     }
 
@@ -202,4 +207,5 @@
             }
         }
     }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/tree/PrettySimpleStringTest.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006033
+ * @summary bug in Pretty.toSimpleString
+ */
+
+import java.io.File;
+
+import javax.tools.StandardJavaFileManager;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.Pretty;
+
+public class PrettySimpleStringTest {
+    public static void main(String... args) throws Exception {
+        new PrettySimpleStringTest().run();
+    }
+
+    void run() throws Exception {
+        File testSrc = new File(System.getProperty("test.src"));
+        File thisFile = new File(testSrc, getClass().getName() + ".java");
+        JavacTool tool = JavacTool.create();
+        StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
+        JavacTask task = tool.getTask(null, fm, null, null, null,
+                fm.getJavaFileObjects(thisFile));
+        Iterable<? extends CompilationUnitTree> trees = task.parse();
+        CompilationUnitTree thisTree = trees.iterator().next();
+
+        {   // test default
+            String thisSrc = Pretty.toSimpleString((JCTree) thisTree);
+            System.err.println(thisSrc);
+            String expect = "import jav[...]} } }";
+            if (!thisSrc.equals(expect)) {
+                throw new Exception("unexpected result");
+            }
+        }
+
+        {   // test explicit length
+            String thisSrc = Pretty.toSimpleString((JCTree) thisTree, 32);
+            System.err.println(thisSrc);
+            String expect = "import java.io.Fil[...]; } } } }";
+            if (!thisSrc.equals(expect)) {
+                throw new Exception("unexpected result");
+            }
+        }
+    }
+}
--- a/langtools/test/tools/javac/varargs/7042566/T7042566.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/varargs/7042566/T7042566.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,22 @@
  * @test
  * @bug 7042566
  * @summary Unambiguous varargs method calls flagged as ambiguous
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main T7042566
  */
 
+import java.io.File;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
 import com.sun.source.util.JavacTask;
 import com.sun.tools.classfile.Instruction;
 import com.sun.tools.classfile.Attribute;
@@ -34,44 +48,36 @@
 import com.sun.tools.classfile.Code_attribute;
 import com.sun.tools.classfile.ConstantPool.*;
 import com.sun.tools.classfile.Method;
-import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.util.List;
 
-import java.io.File;
-import java.net.URI;
-import java.util.Arrays;
-import java.util.Locale;
-import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
-
-public class T7042566 {
+public class T7042566
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     VarargsMethod m1;
     VarargsMethod m2;
     TypeConfiguration actuals;
 
-    T7042566(TypeConfiguration m1_conf, TypeConfiguration m2_conf, TypeConfiguration actuals) {
+    T7042566(TypeConfiguration m1_conf, TypeConfiguration m2_conf,
+            TypeConfiguration actuals) {
         this.m1 = new VarargsMethod(m1_conf);
         this.m2 = new VarargsMethod(m2_conf);
         this.actuals = actuals;
     }
 
-    void compileAndCheck() throws Exception {
+    @Override
+    public void run() {
+        int id = checkCount.incrementAndGet();
         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
-        JavaSource source = new JavaSource();
+        JavaSource source = new JavaSource(id);
         ErrorChecker ec = new ErrorChecker();
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, ec,
+        JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), ec,
                 null, null, Arrays.asList(source));
         ct.call();
-        check(source, ec);
+        check(source, ec, id);
     }
 
-    void check(JavaSource source, ErrorChecker ec) {
-        checkCount++;
+    void check(JavaSource source, ErrorChecker ec, int id) {
         boolean resolutionError = false;
         VarargsMethod selectedMethod = null;
 
@@ -99,13 +105,13 @@
                     "\nFound error: " + ec.errorFound +
                     "\nCompiler diagnostics:\n" + ec.printDiags());
         } else if (!resolutionError) {
-            verifyBytecode(selectedMethod, source);
+            verifyBytecode(selectedMethod, source, id);
         }
     }
 
-    void verifyBytecode(VarargsMethod selected, JavaSource source) {
-        bytecodeCheckCount++;
-        File compiledTest = new File("Test.class");
+    void verifyBytecode(VarargsMethod selected, JavaSource source, int id) {
+        bytecodeCheckCount.incrementAndGet();
+        File compiledTest = new File(String.format("Test%d.class", id));
         try {
             ClassFile cf = ClassFile.read(compiledTest);
             Method testMethod = null;
@@ -118,7 +124,8 @@
             if (testMethod == null) {
                 throw new Error("Test method not found");
             }
-            Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
+            Code_attribute ea =
+                (Code_attribute)testMethod.attributes.get(Attribute.Code);
             if (testMethod == null) {
                 throw new Error("Code attribute for test() method not found");
             }
@@ -127,11 +134,12 @@
                 if (i.getMnemonic().equals("invokevirtual")) {
                     int cp_entry = i.getUnsignedShort(1);
                     CONSTANT_Methodref_info methRef =
-                            (CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry);
+                        (CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry);
                     String type = methRef.getNameAndTypeInfo().getType();
                     String sig = selected.parameterTypes.bytecodeSigStr;
                     if (!type.contains(sig)) {
-                        throw new Error("Unexpected type method call: " + type + "" +
+                        throw new Error("Unexpected type method call: " +
+                                        type + "" +
                                         "\nfound: " + sig +
                                         "\n" + source.getCharContent(true));
                     }
@@ -146,7 +154,7 @@
 
     class JavaSource extends SimpleJavaFileObject {
 
-        static final String source_template = "class Test {\n" +
+        static final String source_template = "class Test#ID {\n" +
                 "   #V1\n" +
                 "   #V2\n" +
                 "   void test() { m(#E); }\n" +
@@ -154,11 +162,13 @@
 
         String source;
 
-        public JavaSource() {
-            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
-            source = source_template.replaceAll("#V1", m1.toString()).
-                    replaceAll("#V2", m2.toString()).
-                    replaceAll("#E", actuals.expressionListStr);
+        public JavaSource(int id) {
+            super(URI.create(String.format("myfo:/Test%d.java", id)),
+                    JavaFileObject.Kind.SOURCE);
+            source = source_template.replaceAll("#V1", m1.toString())
+                    .replaceAll("#V2", m2.toString())
+                    .replaceAll("#E", actuals.expressionListStr)
+                    .replaceAll("#ID", String.valueOf(id));
         }
 
         @Override
@@ -167,26 +177,17 @@
         }
     }
 
-    /** global decls ***/
-
-    // Create a single file manager and reuse it for each compile to save time.
-    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
-
-    //statistics
-    static int checkCount = 0;
-    static int bytecodeCheckCount = 0;
-
     public static void main(String... args) throws Exception {
         for (TypeConfiguration tconf1 : TypeConfiguration.values()) {
             for (TypeConfiguration tconf2 : TypeConfiguration.values()) {
                 for (TypeConfiguration tconf3 : TypeConfiguration.values()) {
-                    new T7042566(tconf1, tconf2, tconf3).compileAndCheck();
+                    pool.execute(new T7042566(tconf1, tconf2, tconf3));
                 }
             }
         }
 
-        System.out.println("Total checks made: " + checkCount);
-        System.out.println("Bytecode checks made: " + bytecodeCheckCount);
+        outWriter.println("Bytecode checks made: " + bytecodeCheckCount.get());
+        checkAfterExec();
     }
 
     enum TypeKind {
@@ -326,14 +327,16 @@
         }
     }
 
-    static class ErrorChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class ErrorChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         boolean errorFound;
         List<String> errDiags = List.nil();
 
         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
             if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
-                errDiags = errDiags.append(diagnostic.getMessage(Locale.getDefault()));
+                errDiags = errDiags
+                        .append(diagnostic.getMessage(Locale.getDefault()));
                 errorFound = true;
             }
         }
@@ -347,4 +350,8 @@
             return buf.toString();
         }
     }
+
+    //number of bytecode checks made while running combo tests
+    static AtomicInteger bytecodeCheckCount = new AtomicInteger();
+
 }
--- a/langtools/test/tools/javac/varargs/warning/Warn4.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/varargs/warning/Warn4.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,11 @@
  * @bug     6945418 6993978
  * @summary Project Coin: Simplified Varargs Method Invocation
  * @author  mcimadamore
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
  * @run main Warn4
  */
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.JavacTool;
+
 import java.net.URI;
 import java.util.Arrays;
 import java.util.Set;
@@ -38,16 +39,19 @@
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
 import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
 
-public class Warn4 {
+public class Warn4
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     final static Warning[] error = null;
     final static Warning[] none = new Warning[] {};
     final static Warning[] vararg = new Warning[] { Warning.VARARGS };
     final static Warning[] unchecked = new Warning[] { Warning.UNCHECKED };
-    final static Warning[] both = new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
+    final static Warning[] both =
+            new Warning[] { Warning.VARARGS, Warning.UNCHECKED };
 
     enum Warning {
         UNCHECKED("generic.array.creation"),
@@ -59,8 +63,10 @@
             this.key = key;
         }
 
-        boolean isSuppressed(TrustMe trustMe, SourceLevel source, SuppressLevel suppressLevelClient,
-                SuppressLevel suppressLevelDecl, ModifierKind modKind) {
+        boolean isSuppressed(TrustMe trustMe, SourceLevel source,
+                SuppressLevel suppressLevelClient,
+                SuppressLevel suppressLevelDecl,
+                ModifierKind modKind) {
             switch(this) {
                 case VARARGS:
                     return source == SourceLevel.JDK_6 ||
@@ -68,7 +74,8 @@
                             trustMe == TrustMe.TRUST;
                 case UNCHECKED:
                     return suppressLevelClient == SuppressLevel.UNCHECKED ||
-                        (trustMe == TrustMe.TRUST && modKind != ModifierKind.NONE && source == SourceLevel.JDK_7);
+                        (trustMe == TrustMe.TRUST && modKind !=
+                            ModifierKind.NONE && source == SourceLevel.JDK_7);
             }
 
             SuppressLevel supLev = this == VARARGS ?
@@ -172,13 +179,13 @@
                             for (Signature vararg_meth : Signature.values()) {
                                 for (Signature client_meth : Signature.values()) {
                                     if (vararg_meth.isApplicableTo(client_meth)) {
-                                        test(sourceLevel,
+                                        pool.execute(new Warn4(sourceLevel,
                                                 trustMe,
                                                 suppressLevelClient,
                                                 suppressLevelDecl,
                                                 modKind,
                                                 vararg_meth,
-                                                client_meth);
+                                                client_meth));
                                     }
                                 }
                             }
@@ -187,63 +194,82 @@
                 }
             }
         }
+
+        checkAfterExec();
     }
 
-    // Create a single file manager and reuse it for each compile to save time.
-    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
+    SourceLevel sourceLevel;
+    TrustMe trustMe;
+    SuppressLevel suppressLevelClient;
+    SuppressLevel suppressLevelDecl;
+    ModifierKind modKind;
+    Signature vararg_meth;
+    Signature client_meth;
+    DiagnosticChecker diagChecker;
 
-    static void test(SourceLevel sourceLevel, TrustMe trustMe, SuppressLevel suppressLevelClient,
-            SuppressLevel suppressLevelDecl, ModifierKind modKind, Signature vararg_meth, Signature client_meth) throws Exception {
+    public Warn4(SourceLevel sourceLevel, TrustMe trustMe,
+            SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
+            ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
+        this.sourceLevel = sourceLevel;
+        this.trustMe = trustMe;
+        this.suppressLevelClient = suppressLevelClient;
+        this.suppressLevelDecl = suppressLevelDecl;
+        this.modKind = modKind;
+        this.vararg_meth = vararg_meth;
+        this.client_meth = client_meth;
+        this.diagChecker = new DiagnosticChecker();
+    }
+
+    @Override
+    public void run() {
+        int id = checkCount.incrementAndGet();
         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
-        JavaSource source = new JavaSource(trustMe, suppressLevelClient, suppressLevelDecl, modKind, vararg_meth, client_meth);
-        DiagnosticChecker dc = new DiagnosticChecker();
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
+        JavaSource source = new JavaSource(id);
+        JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), diagChecker,
                 Arrays.asList("-Xlint:unchecked", "-source", sourceLevel.sourceKey),
                 null, Arrays.asList(source));
-        ct.generate(); //to get mandatory notes
-        check(dc.warnings, sourceLevel,
-                new boolean[] {vararg_meth.giveUnchecked(client_meth),
-                               vararg_meth.giveVarargs(client_meth)},
-                source, trustMe, suppressLevelClient, suppressLevelDecl, modKind);
+        ct.call(); //to get mandatory notes
+        check(source, new boolean[] {vararg_meth.giveUnchecked(client_meth),
+                               vararg_meth.giveVarargs(client_meth)});
     }
 
-    static void check(Set<Warning> warnings, SourceLevel sourceLevel, boolean[] warnArr, JavaSource source,
-            TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl, ModifierKind modKind) {
+    void check(JavaSource source, boolean[] warnArr) {
         boolean badOutput = false;
         for (Warning wkind : Warning.values()) {
             boolean isSuppressed = wkind.isSuppressed(trustMe, sourceLevel,
                     suppressLevelClient, suppressLevelDecl, modKind);
             System.out.println("SUPPRESSED = " + isSuppressed);
-            badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) != warnings.contains(wkind);
+            badOutput |= (warnArr[wkind.ordinal()] && !isSuppressed) !=
+                    diagChecker.warnings.contains(wkind);
         }
         if (badOutput) {
             throw new Error("invalid diagnostics for source:\n" +
                     source.getCharContent(true) +
                     "\nExpected unchecked warning: " + warnArr[0] +
                     "\nExpected unsafe vararg warning: " + warnArr[1] +
-                    "\nWarnings: " + warnings +
+                    "\nWarnings: " + diagChecker.warnings +
                     "\nSource level: " + sourceLevel);
         }
     }
 
-    static class JavaSource extends SimpleJavaFileObject {
+    class JavaSource extends SimpleJavaFileObject {
 
         String source;
 
-        public JavaSource(TrustMe trustMe, SuppressLevel suppressLevelClient, SuppressLevel suppressLevelDecl,
-                ModifierKind modKind, Signature vararg_meth, Signature client_meth) {
-            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+        public JavaSource(int id) {
+            super(URI.create(String.format("myfo:/Test%d.java", id)),
+                    JavaFileObject.Kind.SOURCE);
             String meth1 = vararg_meth.template.replace("#arity", "...");
             meth1 = meth1.replace("#name", "m");
             meth1 = meth1.replace("#body", "");
-            meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() + modKind.mod + meth1;
+            meth1 = trustMe.anno + "\n" + suppressLevelDecl.getSuppressAnno() +
+                    modKind.mod + meth1;
             String meth2 = client_meth.template.replace("#arity", "");
             meth2 = meth2.replace("#name", "test");
             meth2 = meth2.replace("#body", "m(arg);");
             meth2 = suppressLevelClient.getSuppressAnno() + meth2;
-            source = "import java.util.List;\n" +
-                     "class Test {\n" + meth1 +
-                     "\n" + meth2 + "\n}\n";
+            source = String.format("import java.util.List;\n" +
+                     "class Test%s {\n %s \n %s \n } \n", id, meth1, meth2);
         }
 
         @Override
@@ -252,7 +278,8 @@
         }
     }
 
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    static class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         Set<Warning> warnings = new HashSet<>();
 
@@ -267,4 +294,5 @@
             }
         }
     }
+
 }
--- a/langtools/test/tools/javac/varargs/warning/Warn5.java	Thu Jan 10 19:36:13 2013 -0800
+++ b/langtools/test/tools/javac/varargs/warning/Warn5.java	Wed Jan 16 11:58:15 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,10 @@
  * @bug     6993978 7097436
  * @summary Project Coin: Annotation to reduce varargs warnings
  * @author  mcimadamore
+ * @library ../../lib
+ * @build JavacTestingAbstractThreadedTest
  * @run main Warn5
  */
-import com.sun.source.util.JavacTask;
-import com.sun.tools.javac.api.JavacTool;
 import java.net.URI;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -37,10 +37,12 @@
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
 import javax.tools.ToolProvider;
+import com.sun.source.util.JavacTask;
 
-public class Warn5 {
+public class Warn5
+    extends JavacTestingAbstractThreadedTest
+    implements Runnable {
 
     enum XlintOption {
         NONE("none"),
@@ -161,9 +163,6 @@
         REDUNDANT_SAFEVARARGS;
     }
 
-    // Create a single file manager and reuse it for each compile to save time.
-    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
-
     public static void main(String... args) throws Exception {
         for (SourceLevel sourceLevel : SourceLevel.values()) {
             for (XlintOption xlint : XlintOption.values()) {
@@ -173,14 +172,9 @@
                             for (MethodKind methKind : MethodKind.values()) {
                                 for (SignatureKind sig : SignatureKind.values()) {
                                     for (BodyKind body : BodyKind.values()) {
-                                        new Warn5(sourceLevel,
-                                                xlint,
-                                                trustMe,
-                                                suppressLevel,
-                                                modKind,
-                                                methKind,
-                                                sig,
-                                                body).test();
+                                        pool.execute(new Warn5(sourceLevel,
+                                                xlint, trustMe, suppressLevel,
+                                                modKind, methKind, sig, body));
                                     }
                                 }
                             }
@@ -189,6 +183,8 @@
                 }
             }
         }
+
+        checkAfterExec(false);
     }
 
     final SourceLevel sourceLevel;
@@ -202,7 +198,9 @@
     final JavaSource source;
     final DiagnosticChecker dc;
 
-    public Warn5(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe, SuppressLevel suppressLevel, ModifierKind modKind, MethodKind methKind, SignatureKind sig, BodyKind body) {
+    public Warn5(SourceLevel sourceLevel, XlintOption xlint, TrustMe trustMe,
+            SuppressLevel suppressLevel, ModifierKind modKind,
+            MethodKind methKind, SignatureKind sig, BodyKind body) {
         this.sourceLevel = sourceLevel;
         this.xlint = xlint;
         this.trustMe = trustMe;
@@ -215,24 +213,36 @@
         this.dc = new DiagnosticChecker();
     }
 
-    void test() throws Exception {
+    @Override
+    public void run() {
         final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
-        JavacTask ct = (JavacTask)tool.getTask(null, fm, dc,
-                Arrays.asList(xlint.getXlintOption(), "-source", sourceLevel.sourceKey), null, Arrays.asList(source));
-        ct.analyze();
+        JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), dc,
+                Arrays.asList(xlint.getXlintOption(),
+                    "-source", sourceLevel.sourceKey),
+                null, Arrays.asList(source));
+        try {
+            ct.analyze();
+        } catch (Throwable t) {
+            processException(t);
+        }
         check();
     }
 
     void check() {
 
-        EnumSet<WarningKind> expectedWarnings = EnumSet.noneOf(WarningKind.class);
+        EnumSet<WarningKind> expectedWarnings =
+                EnumSet.noneOf(WarningKind.class);
 
         if (sourceLevel == SourceLevel.JDK_7 &&
                 trustMe == TrustMe.TRUST &&
                 suppressLevel != SuppressLevel.VARARGS &&
                 xlint != XlintOption.NONE &&
-                sig.isVarargs && !sig.isReifiableArg && body.hasAliasing &&
-                (methKind == MethodKind.CONSTRUCTOR || (methKind == MethodKind.METHOD && modKind != ModifierKind.NONE))) {
+                sig.isVarargs &&
+                !sig.isReifiableArg &&
+                body.hasAliasing &&
+                (methKind == MethodKind.CONSTRUCTOR ||
+                (methKind == MethodKind.METHOD &&
+                modKind != ModifierKind.NONE))) {
             expectedWarnings.add(WarningKind.UNSAFE_BODY);
         }
 
@@ -247,7 +257,8 @@
         if (sourceLevel == SourceLevel.JDK_7 &&
                 trustMe == TrustMe.TRUST &&
                 (!sig.isVarargs ||
-                (modKind == ModifierKind.NONE && methKind == MethodKind.METHOD))) {
+                (modKind == ModifierKind.NONE &&
+                methKind == MethodKind.METHOD))) {
             expectedWarnings.add(WarningKind.MALFORMED_SAFEVARARGS);
         }
 
@@ -255,7 +266,8 @@
                 trustMe == TrustMe.TRUST &&
                 xlint != XlintOption.NONE &&
                 suppressLevel != SuppressLevel.VARARGS &&
-                (modKind != ModifierKind.NONE || methKind == MethodKind.CONSTRUCTOR) &&
+                (modKind != ModifierKind.NONE ||
+                methKind == MethodKind.CONSTRUCTOR) &&
                 sig.isVarargs &&
                 sig.isReifiableArg) {
             expectedWarnings.add(WarningKind.REDUNDANT_SAFEVARARGS);
@@ -297,19 +309,23 @@
         }
     }
 
-    class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+    class DiagnosticChecker
+        implements javax.tools.DiagnosticListener<JavaFileObject> {
 
         EnumSet<WarningKind> warnings = EnumSet.noneOf(WarningKind.class);
 
         public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
             if (diagnostic.getKind() == Diagnostic.Kind.WARNING) {
-                    if (diagnostic.getCode().contains("unsafe.use.varargs.param")) {
+                    if (diagnostic.getCode().
+                            contains("unsafe.use.varargs.param")) {
                         setWarning(WarningKind.UNSAFE_BODY);
-                    } else if (diagnostic.getCode().contains("redundant.trustme")) {
+                    } else if (diagnostic.getCode().
+                            contains("redundant.trustme")) {
                         setWarning(WarningKind.REDUNDANT_SAFEVARARGS);
                     }
             } else if (diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING &&
-                    diagnostic.getCode().contains("varargs.non.reifiable.type")) {
+                    diagnostic.getCode().
+                        contains("varargs.non.reifiable.type")) {
                 setWarning(WarningKind.UNSAFE_DECL);
             } else if (diagnostic.getKind() == Diagnostic.Kind.ERROR &&
                     diagnostic.getCode().contains("invalid.trustme")) {
@@ -319,7 +335,8 @@
 
         void setWarning(WarningKind wk) {
             if (!warnings.add(wk)) {
-                throw new AssertionError("Duplicate warning of kind " + wk + " in source:\n" + source);
+                throw new AssertionError("Duplicate warning of kind " +
+                        wk + " in source:\n" + source);
             }
         }
 
@@ -327,4 +344,5 @@
             return warnings.contains(wk);
         }
     }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/MaxWarns.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005644
+ * @summary set default max errs and max warns
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class MaxWarns {
+    public static void main(String... args) throws Exception {
+        new MaxWarns().run();
+    }
+
+    void run() throws Exception {
+        final int defaultMaxWarns = 100;
+        final int genWarns = 150;
+        File f = genSrc(genWarns);
+        String out = javadoc(f);
+        check(out, defaultMaxWarns);
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    File genSrc(int count) throws IOException {
+        StringBuilder sb = new StringBuilder();
+        sb.append("package p;\n")
+            .append("public class C {\n")
+            .append("    /**\n");
+        for (int i = 0; i < count; i++)
+            sb.append("     * @param i").append(i).append(" does not exist!\n");
+        sb.append("     */\n")
+            .append("    public void m() { }\n")
+            .append("}\n");
+        File srcDir = new File("src");
+        srcDir.mkdirs();
+        File f = new File(srcDir, "C.java");
+        try (FileWriter fw = new FileWriter(f)) {
+            fw.write(sb.toString());
+        }
+        return f;
+    }
+
+    String javadoc(File f) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        String[] args = { "-d", "api", f.getPath() };
+        int rc = com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw,
+                com.sun.tools.doclets.standard.Standard.class.getName(), args);
+        pw.flush();
+        return sw.toString();
+    }
+
+    void check(String out, int count) {
+        System.err.println(out);
+        Pattern warn = Pattern.compile("warning - @param argument \"i[0-9]+\" is not a parameter name");
+        Matcher m = warn.matcher(out);
+        int n = 0;
+        for (int start = 0; m.find(start); start = m.start() + 1) {
+            n++;
+        }
+        if (n != count)
+            error("unexpected number of warnings reported: " + n + "; expected: " + count);
+
+        Pattern warnCount = Pattern.compile("(?ms).*^([0-9]+) warnings$.*");
+        m = warnCount.matcher(out);
+        if (m.matches()) {
+            n = Integer.parseInt(m.group(1));
+            if (n != count)
+                error("unexpected number of warnings reported: " + n + "; expected: " + count);
+        } else
+            error("total count not found");
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/MethodParameters.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004727 8005647
+ * @summary javac should generate method parameters correctly.
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class MethodParameters {
+
+    static final String Foo_name = "Foo";
+    static final String Foo_contents =
+        ("public class Foo {\n" +
+         "  Foo() {}\n" +
+         "  Foo(int i) {}\n" +
+         "  void foo0() {}\n" +
+         "  void foo2(int j, int k) {}\n" +
+         "}").replaceAll(" +", " ");
+    static final String Init0_expected =
+        ("  Foo();\n" +
+         "    flags: \n" +
+         "    Code:\n" +
+         "      stack=1, locals=1, args_size=1\n" +
+         "         0: aload_0       \n" +
+         "         1: invokespecial #1                  // Method java/lang/Object.\"<init>\":()V\n" +
+         "         4: return        \n" +
+         "      LineNumberTable:\n" +
+         "        line 2: 0").replaceAll(" +", " ");
+    static final String Init1_expected =
+        ("  Foo(int);\n" +
+         "    flags: \n" +
+         "    Code:\n" +
+         "      stack=1, locals=2, args_size=2\n" +
+         "         0: aload_0       \n" +
+         "         1: invokespecial #1                  // Method java/lang/Object.\"<init>\":()V\n" +
+         "         4: return        \n" +
+         "      LineNumberTable:\n" +
+         "        line 3: 0\n" +
+         "    MethodParameters:\n" +
+         "      Name                                Flags\n" +
+         "      i").replaceAll(" +", " ");
+    static final String foo0_expected =
+        ("  void foo0();\n" +
+         "    flags: \n" +
+         "    Code:\n" +
+         "      stack=0, locals=1, args_size=1\n" +
+         "         0: return        \n" +
+         "      LineNumberTable:\n" +
+         "        line 4: 0").replaceAll(" +", " ");
+    static final String foo2_expected =
+        ("  void foo2(int, int);\n" +
+         "    flags: \n" +
+         "    Code:\n" +
+         "      stack=0, locals=3, args_size=3\n" +
+         "         0: return        \n" +
+         "      LineNumberTable:\n" +
+         "        line 5: 0\n" +
+         "    MethodParameters:\n" +
+         "      Name                                Flags\n" +
+         "      j                              \n" +
+         "      k").replaceAll(" +", " ");
+
+    static final File classesdir = new File("methodparameters");
+    static final String separator = System.getProperty("line.separator");
+
+    public static void main(String... args) throws Exception {
+        new MethodParameters().run();
+    }
+
+    void run() throws Exception {
+        classesdir.mkdir();
+        final File Foo_java =
+            writeFile(classesdir, Foo_name + ".java", Foo_contents);
+        compile("-parameters", "-d", classesdir.getPath(), Foo_java.getPath());
+        System.out.println("Run javap");
+        String output =
+            javap("-c", "-verbose", "-classpath",
+                  classesdir.getPath(), Foo_name);
+        String normalized =
+            output.replaceAll(separator, "\n").replaceAll(" +", " ");
+
+        if (!normalized.contains(Init0_expected))
+            error("Bad output for zero-parameter constructor.  Expected\n" +
+                  Init0_expected + "\n" + "but got\n" + normalized);
+        if (!normalized.contains(Init1_expected))
+           error("Bad output for one-parameter constructor.  Expected\n" +
+                 Init1_expected + "\n" + "but got\n" + normalized);
+        if (!normalized.contains(foo0_expected))
+           error("Bad output for zero-parameter method.  Expected\n" +
+                 foo0_expected + "\n" + "but got\n" + normalized);
+        if (!normalized.contains(foo2_expected))
+           error("Bad output for two-parameter method  Expected\n" +
+                 foo2_expected + "\n" + "but got\n" + normalized);
+
+        if (0 != errors)
+            throw new Exception("MethodParameters test failed with " +
+                                errors + " errors");
+    }
+
+    String javap(String... args) {
+        StringWriter sw = new StringWriter();
+        PrintWriter out = new PrintWriter(sw);
+        //sun.tools.javap.Main.entry(args);
+        int rc = com.sun.tools.javap.Main.run(args, out);
+        if (rc != 0)
+            throw new Error("javap failed. rc=" + rc);
+        out.close();
+        System.out.println(sw);
+        return sw.toString();
+    }
+
+    String compile(String... args) throws Exception {
+        System.err.println("compile: " + Arrays.asList(args));
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(args, pw);
+        pw.close();
+        String out = sw.toString();
+        if (out.length() > 0)
+            System.err.println(out);
+        if (rc != 0)
+            error("compilation failed, rc=" + rc);
+        return out;
+    }
+
+    File writeFile(File dir, String path, String body) throws IOException {
+        File f = new File(dir, path);
+        f.getParentFile().mkdirs();
+        FileWriter out = new FileWriter(f);
+        out.write(body);
+        out.close();
+        return f;
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeps/Basic.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8003562
+ * @summary Basic tests for jdeps tool
+ * @build Test p.Foo
+ * @run main Basic
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.*;
+import java.util.regex.*;
+
+public class Basic {
+    public static void main(String... args) throws Exception {
+        int errors = 0;
+
+        errors += new Basic().run();
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+    }
+
+    int run() throws IOException {
+        File testDir = new File(System.getProperty("test.classes", "."));
+        // test a .class file
+        test(new File(testDir, "Test.class"),
+             new String[] {"java.lang", "p"});
+        // test a directory
+        test(new File(testDir, "p"),
+             new String[] {"java.lang", "java.util"});
+        // test class-level dependency output
+        test(new File(testDir, "Test.class"),
+             new String[] {"java.lang.Object", "p.Foo"},
+             new String[] {"-V", "class"});
+        // test -p option
+        test(new File(testDir, "Test.class"),
+             new String[] {"p.Foo"},
+             new String[] {"--verbose-level=class", "-p", "p"});
+        // test -e option
+        test(new File(testDir, "Test.class"),
+             new String[] {"p.Foo"},
+             new String[] {"-V", "class", "-e", "p\\..*"});
+        test(new File(testDir, "Test.class"),
+             new String[] {"java.lang"},
+             new String[] {"-V", "package", "-e", "java\\.lang\\..*"});
+        // test -classpath and -all options
+        test(null,
+             new String[] {"com.sun.tools.jdeps", "java.lang", "java.util",
+                           "java.util.regex", "java.io", "p"},
+             new String[] {"--classpath", testDir.getPath(), "*"});
+        return errors;
+    }
+
+    void test(File file, String[] expect) {
+        test(file, expect, new String[0]);
+    }
+
+    void test(File file, String[] expect, String[] options) {
+        String[] args;
+        if (file != null) {
+            args = Arrays.copyOf(options, options.length+1);
+            args[options.length] = file.getPath();
+        } else {
+            args = options;
+        }
+        String[] deps = jdeps(args);
+        checkEqual("dependencies", expect, deps);
+    }
+
+    String[] jdeps(String... args) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        System.err.println("jdeps " + Arrays.toString(args));
+        int rc = com.sun.tools.jdeps.Main.run(args, pw);
+        pw.close();
+        String out = sw.toString();
+        if (!out.isEmpty())
+            System.err.println(out);
+        if (rc != 0)
+            throw new Error("jdeps failed: rc=" + rc);
+        return findDeps(out);
+    }
+
+    // Pattern used to parse lines
+    private static Pattern linePattern = Pattern.compile(".*\r?\n");
+    private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +.*");
+
+    // Use the linePattern to break the given String into lines, applying
+    // the pattern to each line to see if we have a match
+    private static String[] findDeps(String out) {
+        List<String> result = new ArrayList<>();
+        Matcher lm = linePattern.matcher(out);  // Line matcher
+        Matcher pm = null;                      // Pattern matcher
+        int lines = 0;
+        while (lm.find()) {
+            lines++;
+            CharSequence cs = lm.group();       // The current line
+            if (pm == null)
+                pm = pattern.matcher(cs);
+            else
+                pm.reset(cs);
+            if (pm.find())
+                result.add(pm.group(1));
+            if (lm.end() == out.length())
+                break;
+        }
+        return result.toArray(new String[0]);
+    }
+
+    void checkEqual(String label, String[] expect, String[] found) {
+        Set<String> s1 = new HashSet<>(Arrays.asList(expect));
+        Set<String> s2 = new HashSet<>(Arrays.asList(found));
+
+        if (!s1.equals(s2))
+            error("Unexpected " + label + " found: '" + s2 + "', expected: '" + s1 + "'");
+    }
+
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    int errors;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeps/Test.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class Test {
+    public void test() {
+        p.Foo f = new p.Foo();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeps/p/Foo.java	Wed Jan 16 11:58:15 2013 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package p;
+
+import java.util.List;
+import java.util.Collections;
+public class Foo {
+    public static List foo() {
+        return Collections.emptyList();
+    }
+
+    public Foo() {
+    }
+}