changeset 6514:f26b539bf1d5

Merge
author lana
date Tue, 05 Feb 2013 11:11:53 -0800
parents 0e929be3a9da e526277b51be
children b2fc8e31cecc
files src/share/classes/java/lang/annotation/ContainedBy.java src/share/classes/java/lang/annotation/ContainerFor.java test/java/net/URL/abnormal_http_urls test/java/net/URL/ftp_urls test/java/net/URL/jar_urls test/java/net/URL/normal_http_urls test/java/net/URL/runconstructor.sh test/java/net/URL/share_file_urls test/java/net/URL/win32_file_urls test/sun/net/www/EncDec.doc test/sun/net/www/MarkResetTest.java test/sun/net/www/MarkResetTest.sh test/sun/security/util/Oid/S11N.sh test/sun/security/util/Oid/SerialTest.java
diffstat 113 files changed, 6129 insertions(+), 2143 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/common/architectures/arch-x86_64.properties	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   - Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   - Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+#   - Neither the name of Oracle nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+arch=x86_64
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/netbeans/common/architectures/name-Macosx.properties	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   - Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   - Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+#   - Neither the name of Oracle nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+platform=macosx
--- a/make/netbeans/common/java-data-native.ent	Tue Feb 05 11:10:07 2013 -0800
+++ b/make/netbeans/common/java-data-native.ent	Tue Feb 05 11:11:53 2013 -0800
@@ -39,11 +39,11 @@
         <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
         <built-to>${root}/build/${platform}-${arch}/classes</built-to>
         <javadoc-built-to>${root}/build/${platform}-${arch}/docs/api</javadoc-built-to>
-        <source-level>1.7</source-level>
+        <source-level>1.8</source-level>
     </compilation-unit>
     <compilation-unit>
         <package-root>${root}/test</package-root>
         <unit-tests/>
-        <source-level>1.7</source-level>
+        <source-level>1.8</source-level>
     </compilation-unit>
 </java-data>
--- a/make/netbeans/common/java-data-no-native.ent	Tue Feb 05 11:10:07 2013 -0800
+++ b/make/netbeans/common/java-data-no-native.ent	Tue Feb 05 11:11:53 2013 -0800
@@ -37,11 +37,11 @@
         <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath>
         <built-to>${root}/build/${platform}-${arch}/classes</built-to>
         <javadoc-built-to>${root}/build/${platform}-${arch}/docs/api</javadoc-built-to>
-        <source-level>1.7</source-level>
+        <source-level>1.8</source-level>
     </compilation-unit>
     <compilation-unit>
         <package-root>${root}/test</package-root>
         <unit-tests/>
-        <source-level>1.7</source-level>
+        <source-level>1.8</source-level>
     </compilation-unit>
 </java-data>
--- a/make/netbeans/common/make.xml	Tue Feb 05 11:10:07 2013 -0800
+++ b/make/netbeans/common/make.xml	Tue Feb 05 11:11:53 2013 -0800
@@ -33,7 +33,7 @@
 
 <project name="make" basedir="..">
     
-    <target name="-make.init" depends="-init,-pre-init.linux,-pre-init.solaris,-pre-init.windows">
+    <target name="-make.init" depends="-init,-pre-init.linux,-pre-init.macosx,-pre-init.solaris,-pre-init.windows,-pre-init.macosx">
         <property name="make.options" value=""/> <!-- default, can be overridden per user or per project -->
     </target>
     
@@ -42,6 +42,11 @@
         <property name="make" value="make"/>
     </target>
 
+    <target name="-pre-init.macosx" if="os.macosx">
+        <property name="platform" value="macosx"/>
+        <property name="make" value="make"/>
+    </target>
+
     <target name="-pre-init.solaris" if="os.solaris">
         <property name="platform" value="solaris"/>
         <property name="make" value="gmake"/>
--- a/make/netbeans/common/shared.xml	Tue Feb 05 11:10:07 2013 -0800
+++ b/make/netbeans/common/shared.xml	Tue Feb 05 11:11:53 2013 -0800
@@ -85,6 +85,9 @@
         <property name="includes" value="(nothing)"/>
         <property name="excludes" value=""/>
         <property name="javadoc.dir" location="${build.dir}/javadoc/${ant.project.name}"/>
+        <condition property="os.macosx">
+            <os family="mac"/>
+        </condition>
         <condition property="os.linux">
             <os name="linux"/>
         </condition>
@@ -126,10 +129,6 @@
                 <javac srcdir="@{srcdir}" includes="@{includes}" excludes="@{excludes}" sourcepath="" 
                     destdir="@{classesdir}" fork="true" executable="${bootstrap.javac}"
                     debug="${javac.debug}" debuglevel="${javac.debuglevel}">
-                    <compilerarg value="-source"/>
-                    <compilerarg value="1.5"/>
-                    <compilerarg value="-target"/>
-                    <compilerarg value="1.6"/> <!-- for usability of JDK 6 as snapshot; change to 1.7 when JSR 294 put back -->
                     <!-- Mandatory for compiling partial JDK sources against a snapshot; should NEVER be used for any other purpose: -->
                     <compilerarg value="-XDignore.symbol.file=true"/>
                     <compilerarg line="${javac.options}"/>
--- a/src/share/classes/com/sun/java/util/jar/pack/Attribute.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/Attribute.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1287,19 +1287,24 @@
                 if (localRef == 0) {
                     globalRef = null;  // N.B. global null reference is -1
                 } else {
-                    globalRef = holder.getCPMap()[localRef];
-                    if (e.refKind == CONSTANT_Signature
+                    Entry[] cpMap = holder.getCPMap();
+                    globalRef = (localRef >= 0 && localRef < cpMap.length
+                                    ? cpMap[localRef]
+                                    : null);
+                    byte tag = e.refKind;
+                    if (globalRef != null && tag == CONSTANT_Signature
                         && globalRef.getTag() == CONSTANT_Utf8) {
                         // Cf. ClassReader.readSignatureRef.
                         String typeName = globalRef.stringValue();
                         globalRef = ConstantPool.getSignatureEntry(typeName);
-                    } else if (e.refKind == CONSTANT_FieldSpecific) {
-                        assert(globalRef.getTag() >= CONSTANT_Integer);
-                        assert(globalRef.getTag() <= CONSTANT_String ||
-                               globalRef.getTag() >= CONSTANT_MethodHandle);
-                        assert(globalRef.getTag() <= CONSTANT_MethodType);
-                    } else if (e.refKind < CONSTANT_GroupFirst) {
-                        assert(e.refKind == globalRef.getTag());
+                    }
+                    String got = (globalRef == null
+                        ? "invalid CP index"
+                        : "type=" + ConstantPool.tagName(globalRef.tag));
+                    if (globalRef == null || !globalRef.tagMatches(tag)) {
+                        throw new IllegalArgumentException(
+                                "Bad constant, expected type=" +
+                                ConstantPool.tagName(tag) + " got " + got);
                     }
                 }
                 out.putRef(bandIndex, globalRef);
--- a/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/ClassReader.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@
     Package pkg;
     Class cls;
     long inPos;
+    long constantPoolLimit = -1;
     DataInputStream in;
     Map<Attribute.Layout, Attribute> attrDefs;
     Map<Attribute.Layout, String> attrCommands;
@@ -117,15 +118,33 @@
 
     private Entry readRef(byte tag) throws IOException {
         Entry e = readRef();
-        assert(e != null);
         assert(!(e instanceof UnresolvedEntry));
-        assert(e.tagMatches(tag));
+        checkTag(e, tag);
         return e;
     }
 
+    /** Throw a ClassFormatException if the entry does not match the expected tag type. */
+    private Entry checkTag(Entry e, byte tag) throws ClassFormatException {
+        if (e == null || !e.tagMatches(tag)) {
+            String where = (inPos == constantPoolLimit
+                                ? " in constant pool"
+                                : " at pos: " + inPos);
+            String got = (e == null
+                            ? "null CP index"
+                            : "type=" + ConstantPool.tagName(e.tag));
+            throw new ClassFormatException("Bad constant, expected type=" +
+                    ConstantPool.tagName(tag) +
+                    " got "+ got + ", in File: " + cls.file.nameString + where);
+        }
+        return e;
+    }
+    private Entry checkTag(Entry e, byte tag, boolean nullOK) throws ClassFormatException {
+        return nullOK && e == null ? null : checkTag(e, tag);
+    }
+
     private Entry readRefOrNull(byte tag) throws IOException {
         Entry e = readRef();
-        assert(e == null || e.tagMatches(tag));
+        checkTag(e, tag, true);
         return e;
     }
 
@@ -143,8 +162,10 @@
 
     private SignatureEntry readSignatureRef() throws IOException {
         // The class file stores a Utf8, but we want a Signature.
-        Entry e = readRef(CONSTANT_Utf8);
-        return ConstantPool.getSignatureEntry(e.stringValue());
+        Entry e = readRef(CONSTANT_Signature);
+        return (e != null && e.getTag() == CONSTANT_Utf8)
+                ? ConstantPool.getSignatureEntry(e.stringValue())
+                : (SignatureEntry) e;
     }
 
     void read() throws IOException {
@@ -279,6 +300,7 @@
                             " at pos: " + inPos);
             }
         }
+        constantPoolLimit = inPos;
 
         // Fix up refs, which might be out of order.
         while (fptr > 0) {
@@ -311,25 +333,25 @@
                 case CONSTANT_Fieldref:
                 case CONSTANT_Methodref:
                 case CONSTANT_InterfaceMethodref:
-                    ClassEntry      mclass = (ClassEntry)      cpMap[ref];
-                    DescriptorEntry mdescr = (DescriptorEntry) cpMap[ref2];
+                    ClassEntry      mclass = (ClassEntry)      checkTag(cpMap[ref],  CONSTANT_Class);
+                    DescriptorEntry mdescr = (DescriptorEntry) checkTag(cpMap[ref2], CONSTANT_NameandType);
                     cpMap[cpi] = ConstantPool.getMemberEntry((byte)tag, mclass, mdescr);
                     break;
                 case CONSTANT_NameandType:
-                    Utf8Entry mname = (Utf8Entry) cpMap[ref];
-                    Utf8Entry mtype = (Utf8Entry) cpMap[ref2];
+                    Utf8Entry mname = (Utf8Entry) checkTag(cpMap[ref],  CONSTANT_Utf8);
+                    Utf8Entry mtype = (Utf8Entry) checkTag(cpMap[ref2], CONSTANT_Signature);
                     cpMap[cpi] = ConstantPool.getDescriptorEntry(mname, mtype);
                     break;
                 case CONSTANT_MethodType:
-                    cpMap[cpi] = ConstantPool.getMethodTypeEntry((Utf8Entry) cpMap[ref]);
+                    cpMap[cpi] = ConstantPool.getMethodTypeEntry((Utf8Entry) checkTag(cpMap[ref], CONSTANT_Signature));
                     break;
                 case CONSTANT_MethodHandle:
                     byte refKind = (byte)(-1 ^ ref);
-                    MemberEntry memRef = (MemberEntry) cpMap[ref2];
+                    MemberEntry memRef = (MemberEntry) checkTag(cpMap[ref2], CONSTANT_AnyMember);
                     cpMap[cpi] = ConstantPool.getMethodHandleEntry(refKind, memRef);
                     break;
                 case CONSTANT_InvokeDynamic:
-                    DescriptorEntry idescr = (DescriptorEntry) cpMap[ref2];
+                    DescriptorEntry idescr = (DescriptorEntry) checkTag(cpMap[ref2], CONSTANT_NameandType);
                     cpMap[cpi] = new UnresolvedEntry((byte)tag, (-1 ^ ref), idescr);
                     // Note that ref must be resolved later, using the BootstrapMethods attribute.
                     break;
@@ -541,7 +563,8 @@
         code.max_locals = readUnsignedShort();
         code.bytes = new byte[readInt()];
         in.readFully(code.bytes);
-        Instruction.opcodeChecker(code.bytes);
+        Entry[] cpMap = cls.getCPMap();
+        Instruction.opcodeChecker(code.bytes, cpMap);
         int nh = readUnsignedShort();
         code.setHandlerCount(nh);
         for (int i = 0; i < nh; i++) {
@@ -559,7 +582,7 @@
             MethodHandleEntry bsmRef = (MethodHandleEntry) readRef(CONSTANT_MethodHandle);
             Entry[] argRefs = new Entry[readUnsignedShort()];
             for (int j = 0; j < argRefs.length; j++) {
-                argRefs[j] = readRef();
+                argRefs[j] = readRef(CONSTANT_LoadableValue);
             }
             bsms[i] = ConstantPool.getBootstrapMethodEntry(bsmRef, argRefs);
         }
--- a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -243,8 +243,32 @@
             return tag == CONSTANT_Double || tag == CONSTANT_Long;
         }
 
-        public final boolean tagMatches(int tag) {
-            return (this.tag == tag);
+        public final boolean tagMatches(int matchTag) {
+            if (tag == matchTag)
+                return true;
+            byte[] allowedTags;
+            switch (matchTag) {
+                case CONSTANT_All:
+                    return true;
+                case CONSTANT_Signature:
+                    return tag == CONSTANT_Utf8;  // format check also?
+                case CONSTANT_LoadableValue:
+                    allowedTags = LOADABLE_VALUE_TAGS;
+                    break;
+                case CONSTANT_AnyMember:
+                    allowedTags = ANY_MEMBER_TAGS;
+                    break;
+                case CONSTANT_FieldSpecific:
+                    allowedTags = FIELD_SPECIFIC_TAGS;
+                    break;
+                default:
+                    return false;
+            }
+            for (byte b : allowedTags) {
+                if (b == tag)
+                    return true;
+            }
+            return false;
         }
 
         public String toString() {
--- a/src/share/classes/com/sun/java/util/jar/pack/Instruction.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/Instruction.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -647,7 +647,7 @@
         }
     }
 
-    public static void opcodeChecker(byte[] code) throws FormatException {
+    public static void opcodeChecker(byte[] code, ConstantPool.Entry[] cpMap) throws FormatException {
         Instruction i = at(code, 0);
         while (i != null) {
             int opcode = i.getBC();
@@ -655,6 +655,16 @@
                 String message = "illegal opcode: " + opcode + " " + i;
                 throw new FormatException(message);
             }
+            ConstantPool.Entry e = i.getCPRef(cpMap);
+            if (e != null) {
+                byte tag = i.getCPTag();
+                if (!e.tagMatches(tag)) {
+                    String message = "illegal reference, expected type=" +
+                                     ConstantPool.tagName(tag) + ": " +
+                                     i.toString(cpMap);
+                    throw new FormatException(message);
+                }
+            }
             i = i.next();
         }
     }
--- a/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/PackageWriter.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1618,6 +1618,16 @@
                     bc_which = null;
                     assert(false);
                 }
+                if (ref != null && bc_which.index != null && !bc_which.index.contains(ref)) {
+                    // Crash and burn with a complaint if there are funny
+                    // references for this bytecode instruction.
+                    // Example:  invokestatic of a CONSTANT_InterfaceMethodref.
+                    String complaint = code.getMethod() +
+                        " contains a bytecode " + i +
+                        " with an unsupported constant reference; please use the pass-file option on this class.";
+                    Utils.log.warning(complaint);
+                    throw new IOException(complaint);
+                }
                 bc_codes.putByte(vbc);
                 bc_which.putRef(ref);
                 // handle trailing junk
--- a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Tue Feb 05 11:11:53 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
@@ -180,6 +180,15 @@
             }
             unknownAttrCommand = uaMode.intern();
         }
+        final String classFormatCommand;
+        {
+            String fmtMode = props.getProperty(Utils.CLASS_FORMAT_ERROR, Pack200.Packer.PASS);
+            if (!(Pack200.Packer.PASS.equals(fmtMode) ||
+                  Pack200.Packer.ERROR.equals(fmtMode))) {
+                throw new RuntimeException("Bad option: " + Utils.CLASS_FORMAT_ERROR + " = " + fmtMode);
+            }
+            classFormatCommand = fmtMode.intern();
+        }
 
         final Map<Attribute.Layout, Attribute> attrDefs;
         final Map<Attribute.Layout, String> attrCommands;
@@ -505,8 +514,7 @@
                     }
                 } else if (ioe instanceof ClassReader.ClassFormatException) {
                     ClassReader.ClassFormatException ce = (ClassReader.ClassFormatException) ioe;
-                    // %% TODO: Do we invent a new property for this or reuse %%
-                    if (unknownAttrCommand.equals(Pack200.Packer.PASS)) {
+                    if (classFormatCommand.equals(Pack200.Packer.PASS)) {
                         Utils.log.info(ce.toString());
                         Utils.log.warning(message + " unknown class format: " +
                                 fname);
--- a/src/share/classes/com/sun/java/util/jar/pack/PropMap.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/PropMap.java	Tue Feb 05 11:11:53 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
@@ -112,6 +112,11 @@
         // Pass through files with unrecognized attributes by default.
         props.put(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
 
+        // Pass through files with unrecognized format by default, also
+        // allow system property to be set
+        props.put(Utils.CLASS_FORMAT_ERROR,
+                System.getProperty(Utils.CLASS_FORMAT_ERROR, Pack200.Packer.PASS));
+
         // Default effort is 5, midway between 1 and 9.
         props.put(Pack200.Packer.EFFORT, "5");
 
--- a/src/share/classes/com/sun/java/util/jar/pack/Utils.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/Utils.java	Tue Feb 05 11:11:53 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
@@ -122,6 +122,12 @@
      */
     static final String PACK_ZIP_ARCHIVE_MARKER_COMMENT = "PACK200";
 
+    /*
+     * behaviour when we hit a class format error, but not necessarily
+     * an unknown attribute, by default it is allowed to PASS.
+     */
+    static final String CLASS_FORMAT_ERROR = COM_PREFIX+"class.format.error";
+
     // Keep a TLS point to the global data and environment.
     // This makes it simpler to supply environmental options
     // to the engine code, especially the native code.
--- a/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Tue Feb 05 11:11:53 2013 -0800
@@ -50,8 +50,6 @@
 import javax.management.NotCompliantMBeanException;
 
 import com.sun.jmx.remote.util.EnvHelp;
-import java.beans.BeanInfo;
-import java.beans.PropertyDescriptor;
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import javax.management.AttributeNotFoundException;
--- a/src/share/classes/java/lang/Class.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/Class.java	Tue Feb 05 11:11:53 2013 -0800
@@ -29,12 +29,14 @@
 import java.lang.reflect.GenericArrayType;
 import java.lang.reflect.Member;
 import java.lang.reflect.Field;
+import java.lang.reflect.Executable;
 import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.AnnotatedType;
 import java.lang.ref.SoftReference;
 import java.io.InputStream;
 import java.io.ObjectStreamField;
@@ -2325,6 +2327,11 @@
 
     // Annotations handling
     private native byte[] getRawAnnotations();
+    // Since 1.8
+    native byte[] getRawTypeAnnotations();
+    static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
+        return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
+    }
 
     native ConstantPool getConstantPool();
 
@@ -3068,21 +3075,12 @@
      * @throws NullPointerException {@inheritDoc}
      * @since 1.5
      */
+    @SuppressWarnings("unchecked")
     public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         Objects.requireNonNull(annotationClass);
 
         initAnnotationsIfNecessary();
-        return AnnotationSupport.getOneAnnotation(annotations, annotationClass);
-    }
-
-    /**
-     * @throws NullPointerException {@inheritDoc}
-     * @since 1.5
-     */
-    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-        Objects.requireNonNull(annotationClass);
-
-        return getAnnotation(annotationClass) != null;
+        return (A) annotations.get(annotationClass);
     }
 
     /**
@@ -3101,18 +3099,19 @@
      */
     public Annotation[] getAnnotations() {
         initAnnotationsIfNecessary();
-        return AnnotationSupport.unpackToArray(annotations);
+        return AnnotationParser.toArray(annotations);
     }
 
     /**
      * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
+    @SuppressWarnings("unchecked")
     public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
         Objects.requireNonNull(annotationClass);
 
         initAnnotationsIfNecessary();
-        return AnnotationSupport.getOneAnnotation(declaredAnnotations, annotationClass);
+        return (A) declaredAnnotations.get(annotationClass);
     }
 
     /**
@@ -3131,17 +3130,7 @@
      */
     public Annotation[] getDeclaredAnnotations()  {
         initAnnotationsIfNecessary();
-        return AnnotationSupport.unpackToArray(declaredAnnotations);
-    }
-
-    /** Returns one "directly" present annotation or null */
-    <A extends Annotation> A getDirectDeclaredAnnotation(Class<A> annotationClass) {
-        Objects.requireNonNull(annotationClass);
-
-        initAnnotationsIfNecessary();
-        @SuppressWarnings("unchecked") // TODO check safe
-        A ret = (A)declaredAnnotations.get(annotationClass);
-        return ret;
+        return AnnotationParser.toArray(declaredAnnotations);
     }
 
     // Annotations cache
@@ -3196,4 +3185,53 @@
      * Maintained by the ClassValue class.
      */
     transient ClassValue.ClassValueMap classValueMap;
+
+    /**
+     * Returns an AnnotatedType object that represents the use of a type to specify
+     * the superclass of the entity represented by this Class. (The <em>use</em> of type
+     * Foo to specify the superclass in '... extends Foo' is distinct from the
+     * <em>declaration</em> of type Foo.)
+     *
+     * If this Class represents a class type whose declaration does not explicitly
+     * indicate an annotated superclass, the return value is null.
+     *
+     * If this Class represents either the Object class, an interface type, an
+     * array type, a primitive type, or void, the return value is null.
+     *
+     * @since 1.8
+     */
+    public AnnotatedType getAnnotatedSuperclass() {
+         return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
 }
+
+    /**
+     * Returns an array of AnnotatedType objects that represent the use of types to
+     * specify superinterfaces of the entity represented by this Class. (The <em>use</em>
+     * of type Foo to specify a superinterface in '... implements Foo' is
+     * distinct from the <em>declaration</em> of type Foo.)
+     *
+     * If this Class represents a class, the return value is an array
+     * containing objects representing the uses of interface types to specify
+     * interfaces implemented by the class. The order of the objects in the
+     * array corresponds to the order of the interface types used in the
+     * 'implements' clause of the declaration of this Class.
+     *
+     * If this Class represents an interface, the return value is an array
+     * containing objects representing the uses of interface types to specify
+     * interfaces directly extended by the interface. The order of the objects in
+     * the array corresponds to the order of the interface types used in the
+     * 'extends' clause of the declaration of this Class.
+     *
+     * If this Class represents a class or interface whose declaration does not
+     * explicitly indicate any annotated superinterfaces, the return value is an
+     * array of length 0.
+     *
+     * If this Class represents either the Object class, an array type, a
+     * primitive type, or void, the return value is an array of length 0.
+     *
+     * @since 1.8
+     */
+    public AnnotatedType[] getAnnotatedInterfaces() {
+         return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
+    }
+}
--- a/src/share/classes/java/lang/Double.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/Double.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -289,7 +289,7 @@
             return Double.toString(d);
         else {
             // Initialized to maximum size of output.
-            StringBuffer answer = new StringBuffer(24);
+            StringBuilder answer = new StringBuilder(24);
 
             if (Math.copySign(1.0, d) == -1.0)    // value is negative,
                 answer.append("-");                  // so append sign info
@@ -300,8 +300,7 @@
 
             if(d == 0.0) {
                 answer.append("0.0p0");
-            }
-            else {
+            } else {
                 boolean subnormal = (d < DoubleConsts.MIN_NORMAL);
 
                 // Isolate significand bits and OR in a high-order bit
@@ -324,13 +323,14 @@
                               "0":
                               signif.replaceFirst("0{1,12}$", ""));
 
+                answer.append('p');
                 // If the value is subnormal, use the E_min exponent
                 // value for double; otherwise, extract and report d's
                 // exponent (the representation of a subnormal uses
                 // E_min -1).
-                answer.append("p" + (subnormal ?
-                               DoubleConsts.MIN_EXPONENT:
-                               Math.getExponent(d) ));
+                answer.append(subnormal ?
+                              DoubleConsts.MIN_EXPONENT:
+                              Math.getExponent(d));
             }
             return answer.toString();
         }
--- a/src/share/classes/java/lang/Package.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/Package.java	Tue Feb 05 11:11:53 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
@@ -387,15 +387,6 @@
 
     /**
      * @throws NullPointerException {@inheritDoc}
-     * @since 1.5
-     */
-    public boolean isAnnotationPresent(
-        Class<? extends Annotation> annotationClass) {
-        return getPackageInfo().isAnnotationPresent(annotationClass);
-    }
-
-    /**
-     * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
     public  <A extends Annotation> A[] getAnnotations(Class<A> annotationClass) {
--- a/src/share/classes/java/lang/System.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/System.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 package java.lang;
 
 import java.io.*;
-import java.lang.annotation.Annotation;
+import java.lang.reflect.Executable;
 import java.util.Properties;
 import java.util.PropertyPermission;
 import java.util.StringTokenizer;
@@ -1196,8 +1196,11 @@
             public AnnotationType getAnnotationType(Class<?> klass) {
                 return klass.getAnnotationType();
             }
-            public <A extends Annotation> A getDirectDeclaredAnnotation(Class<?> klass, Class<A> anno) {
-                return klass.getDirectDeclaredAnnotation(anno);
+            public byte[] getRawClassTypeAnnotations(Class<?> klass) {
+                return klass.getRawTypeAnnotations();
+            }
+            public byte[] getRawExecutableTypeAnnotations(Executable executable) {
+                return Class.getExecutableTypeAnnotationBytes(executable);
             }
             public <E extends Enum<E>>
                     E[] getEnumConstantsShared(Class<E> klass) {
--- a/src/share/classes/java/lang/annotation/ContainedBy.java	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.ContainedBy} is
- * used to indicate that the annotation type whose declaration it
- * (meta-)annotates is <em>repeatable</em>. The value of
- * {@code @ContainedBy} indicates the <em>containing annotation
- * type</em> for the repeatable annotation type.
- *
- * <p>The pair of annotation types {@code @ContainedBy} and
- * {@link java.lang.annotation.ContainerFor @ContainerFor} are used to
- * indicate that annotation types are repeatable. Specifically:
- *
- * <ul>
- * <li>The annotation type {@code @ContainedBy} is used on the
- * declaration of a repeatable annotation type (JLS 9.6) to indicate
- * its containing annotation type.
- *
- * <li>The annotation type {@code @ContainerFor} is used on the
- * declaration of a containing annotation type (JLS 9.6) to indicate
- * the repeatable annotation type for which it serves as the
- * containing annotation type.
- * </ul>
- *
- * <p>
- * An inconsistent pair of {@code @ContainedBy} and
- * {@code @ContainerFor} annotations on a repeatable annotation type
- * and its containing annotation type (JLS 9.6) will lead to
- * compile-time errors and runtime exceptions when using reflection to
- * read annotations of a repeatable type.
- *
- * @see java.lang.annotation.ContainerFor
- * @since 1.8
- * @jls 9.6 Annotation Types
- * @jls 9.7 Annotations
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.ANNOTATION_TYPE)
-public @interface ContainedBy {
-    /**
-     * Indicates the <em>containing annotation type</em> for the
-     * repeatable annotation type.
-     */
-    Class<? extends Annotation> value();
-}
--- a/src/share/classes/java/lang/annotation/ContainerFor.java	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.ContainerFor} is
- * used to indicate that the annotation type whose declaration it
- * (meta-)annotates is a <em>containing annotation type</em>. The
- * value of {@code @ContainerFor} indicates the <em>repeatable
- * annotation type</em> for the containing annotation type.
- *
- * <p>The pair of annotation types {@link
- * java.lang.annotation.ContainedBy @ContainedBy} and
- * {@code @ContainerFor} are used to indicate that annotation types
- * are repeatable. Specifically:
- *
- * <ul>
- * <li>The annotation type {@code @ContainedBy} is used on the
- * declaration of a repeatable annotation type (JLS 9.6) to indicate
- * its containing annotation type.
- *
- * <li>The annotation type {@code @ContainerFor} is used on the
- * declaration of a containing annotation type (JLS 9.6) to indicate
- * the repeatable annotation type for which it serves as the
- * containing annotation type.
- * </ul>
- *
- * <p>
- * An inconsistent pair of {@code @ContainedBy} and
- * {@code @ContainerFor} annotations on a repeatable annotation type
- * and its containing annotation type (JLS 9.6) will lead to
- * compile-time errors and runtime exceptions when using reflection to
- * read annotations of a repeatable type.
- *
- * @see java.lang.annotation.ContainedBy
- * @since 1.8
- * @jls 9.6 Annotation Types
- * @jls 9.7 Annotations
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.ANNOTATION_TYPE)
-public @interface ContainerFor {
-
-    /**
-     * Indicates the repeatable annotation type for the containing
-     * annotation type.
-     */
-    Class<? extends Annotation> value();
-}
--- a/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/annotation/InvalidContainerAnnotationError.java	Tue Feb 05 11:11:53 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,10 +27,9 @@
 import java.util.Objects;
 
 /**
- * Thrown to indicate that an annotation type whose declaration is
- * (meta-)annotated with a {@link ContainerFor} annotation is not, in
- * fact, the <em>containing annotation type of the type named by {@link
- * ContainerFor}</em>.
+ * Thrown to indicate that an annotation type expected to act as a
+ * container for another annotation type by virture of an @Repeatable
+ * annotation, does not act as a container.
  *
  * @see   java.lang.reflect.AnnotatedElement
  * @since 1.8
--- a/src/share/classes/java/lang/reflect/AccessibleObject.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/AccessibleObject.java	Tue Feb 05 11:11:53 2013 -0800
@@ -182,14 +182,6 @@
 
     /**
      * @throws NullPointerException {@inheritDoc}
-     * @since 1.5
-     */
-    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-        return getAnnotation(annotationClass) != null;
-    }
-
-    /**
-     * @throws NullPointerException {@inheritDoc}
      * @since 1.8
      */
     public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/reflect/AnnotatedArrayType.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+
+/**
+ * AnnotatedArrayType represents the use of an array type, whose component
+ * type may itself represent the annotated use of a type.
+ *
+ * @since 1.8
+ */
+public interface AnnotatedArrayType extends AnnotatedType {
+
+    /**
+     * Returns the annotated generic component type of this array type.
+     *
+     * @return the annotated generic component type of this array type
+     */
+    AnnotatedType  getAnnotatedGenericComponentType();
+}
--- a/src/share/classes/java/lang/reflect/AnnotatedElement.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/AnnotatedElement.java	Tue Feb 05 11:11:53 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
@@ -35,6 +35,24 @@
  * arrays returned by accessors for array-valued enum members; it will
  * have no affect on the arrays returned to other callers.
  *
+ * <p>An annotation A is <em>directly present</em> on an element E if the
+ * RuntimeVisibleAnnotations or RuntimeVisibleParameterAnnotations attribute
+ * associated with E either:
+ * <ul>
+ * <li>contains A; or
+ * <li>for invocations of get[Declared]Annotations(Class<T>),
+ * contains A or exactly one annotation C whose type is the containing
+ * annotation type of A's type (JLS 9.6) and whose value element contains A
+ * </ul>
+ *
+ * <p>An annotation A is <em>present</em> on an element E if either:
+ * <ul>
+ * <li>A is <em>directly present</em> on E; or
+ * <li>There are no annotations of A's type which are <em>directly present</em>
+ * on E, and E is a class, and A's type is inheritable (JLS 9.6.3.3), and A is
+ * present on the superclass of E
+ * </ul>
+ *
  * <p>If an annotation returned by a method in this interface contains
  * (directly or indirectly) a {@link Class}-valued member referring to
  * a class that is not accessible in this VM, attempting to read the class
@@ -50,7 +68,7 @@
  * containing annotation type of T will result in an
  * InvalidContainerAnnotationError.
  *
- * <p>Finally, Attempting to read a member whose definition has evolved
+ * <p>Finally, attempting to read a member whose definition has evolved
  * incompatibly will result in a {@link
  * java.lang.annotation.AnnotationTypeMismatchException} or an
  * {@link java.lang.annotation.IncompleteAnnotationException}.
@@ -70,6 +88,12 @@
      * is present on this element, else false.  This method
      * is designed primarily for convenient access to marker annotations.
      *
+     * <p>The truth value returned by this method is equivalent to:
+     * {@code getAnnotation(annotationClass) != null}
+     *
+     * <p>The body of the default method is specified to be the code
+     * above.
+     *
      * @param annotationClass the Class object corresponding to the
      *        annotation type
      * @return true if an annotation for the specified annotation
@@ -77,7 +101,9 @@
      * @throws NullPointerException if the given annotation class is null
      * @since 1.5
      */
-     boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
+    default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return getAnnotation(annotationClass) != null;
+    }
 
    /**
      * Returns this element's annotation for the specified type if
@@ -110,12 +136,15 @@
     <T extends Annotation> T[] getAnnotations(Class<T> annotationClass);
 
     /**
-     * Returns all annotations present on this element.  (Returns an array
-     * of length zero if this element has no annotations.)  The caller of
-     * this method is free to modify the returned array; it will have no
-     * effect on the arrays returned to other callers.
+     * Returns annotations that are <em>present</em> on this element.
      *
-     * @return all annotations present on this element
+     * If there are no annotations <em>present</em> on this element, the return
+     * value is an array of length 0.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
+     *
+     * @return annotations present on this element
      * @since 1.5
      */
     Annotation[] getAnnotations();
@@ -157,14 +186,16 @@
     <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass);
 
     /**
-     * Returns all annotations that are directly present on this
-     * element. This method ignores inherited annotations. (Returns
-     * an array of length zero if no annotations are directly present
-     * on this element.)  The caller of this method is free to modify
-     * the returned array; it will have no effect on the arrays
-     * returned to other callers.
+     * Returns annotations that are <em>directly present</em> on this element.
+     * This method ignores inherited annotations.
      *
-     * @return All annotations directly present on this element
+     * If there are no annotations <em>directly present</em> on this element,
+     * the return value is an array of length 0.
+     *
+     * The caller of this method is free to modify the returned array; it will
+     * have no effect on the arrays returned to other callers.
+     *
+     * @return annotations directly present on this element
      * @since 1.5
      */
     Annotation[] getDeclaredAnnotations();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/reflect/AnnotatedParameterizedType.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+/**
+ * AnnotatedParameterizedType represents the use of a parameterized type,
+ * whose type arguments may themselves represent annotated uses of types.
+ *
+ * @since 1.8
+ */
+public interface AnnotatedParameterizedType extends AnnotatedType {
+
+    /**
+     * Returns the annotated actual type arguments of this parameterized type.
+     *
+     * @return the annotated actual type arguments of this parameterized type
+     */
+    AnnotatedType[] getAnnotatedActualTypeArguments();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/reflect/AnnotatedType.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+/**
+ * AnnotatedType represents the annotated use of a type in the program
+ * currently running in this VM. The use may be of any type in the Java
+ * programming language, including an array type, a parameterized type, a type
+ * variable, or a wildcard type.
+ *
+ * @since 1.8
+ */
+public interface AnnotatedType extends AnnotatedElement {
+
+    /**
+     * Returns the underlying type that this annotated type represents.
+     *
+     * @return the type this annotated type represents
+     */
+    public Type getType();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/reflect/AnnotatedTypeVariable.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+/**
+ * AnnotatedTypeVariable represents the use of a type variable, whose
+ * declaration may have bounds which themselves represent annotated uses of
+ * types.
+ *
+ * @since 1.8
+ */
+public interface AnnotatedTypeVariable extends AnnotatedType {
+
+    /**
+     * Returns the annotated bounds of this type variable.
+     *
+     * @return the annotated bounds of this type variable
+     */
+    AnnotatedType[] getAnnotatedBounds();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/lang/reflect/AnnotatedWildcardType.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.reflect;
+
+/**
+ * AnnotatedWildcardType represents the use of a wildcard type argument, whose
+ * upper or lower bounds may themselves represent annotated uses of types.
+ *
+ * @since 1.8
+ */
+public interface AnnotatedWildcardType extends AnnotatedType {
+
+    /**
+     * Returns the annotated lower bounds of this wildcard type.
+     *
+     * @return the annotated lower bounds of this wildcard type
+     */
+    AnnotatedType[] getAnnotatedLowerBounds();
+
+    /**
+     * Returns the annotated upper bounds of this wildcard type.
+     *
+     * @return the annotated upper bounds of this wildcard type
+     */
+    AnnotatedType[] getAnnotatedUpperBounds();
+}
--- a/src/share/classes/java/lang/reflect/Constructor.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/Constructor.java	Tue Feb 05 11:11:53 2013 -0800
@@ -154,6 +154,10 @@
     byte[] getAnnotationBytes() {
         return annotations;
     }
+    @Override
+    byte[] getTypeAnnotationBytes() {
+        return typeAnnotations;
+    }
 
     /**
      * {@inheritDoc}
@@ -523,4 +527,12 @@
             }
         }
     }
+
+    /**
+     * {@inheritDoc}
+     * @since 1.8
+     */
+    public AnnotatedType getAnnotatedReturnType() {
+        return getAnnotatedReturnType0(getDeclaringClass());
+    }
 }
--- a/src/share/classes/java/lang/reflect/Executable.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/Executable.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 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,11 +26,12 @@
 package java.lang.reflect;
 
 import java.lang.annotation.*;
-import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
 import sun.reflect.annotation.AnnotationParser;
 import sun.reflect.annotation.AnnotationSupport;
+import sun.reflect.annotation.TypeAnnotationParser;
+import sun.reflect.annotation.TypeAnnotation;
 import sun.reflect.generics.repository.ConstructorRepository;
 
 /**
@@ -50,6 +51,7 @@
      * Accessor method to allow code sharing
      */
     abstract byte[] getAnnotationBytes();
+    abstract byte[] getTypeAnnotationBytes();
 
     /**
      * Does the Executable have generic information.
@@ -435,8 +437,7 @@
      */
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-
-        return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass);
+        return annotationClass.cast(declaredAnnotations().get(annotationClass));
     }
 
     /**
@@ -454,7 +455,7 @@
      * {@inheritDoc}
      */
     public Annotation[] getDeclaredAnnotations()  {
-        return AnnotationSupport.unpackToArray(declaredAnnotations());
+        return AnnotationParser.toArray(declaredAnnotations());
     }
 
     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
@@ -470,4 +471,86 @@
         return declaredAnnotations;
     }
 
+
+    /* Helper for subclasses of Executable.
+     *
+     * Returns an AnnotatedType object that represents the use of a type to
+     * specify the return type of the method/constructor represented by this
+     * Executable.
+     *
+     * @since 1.8
+     */
+    AnnotatedType getAnnotatedReturnType0(Type returnType) {
+        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
+                                                       sun.misc.SharedSecrets.getJavaLangAccess().
+                                                           getConstantPool(getDeclaringClass()),
+                                                       this,
+                                                       getDeclaringClass(),
+                                                       returnType,
+                                                       TypeAnnotation.TypeAnnotationTarget.METHOD_RETURN_TYPE);
+    }
+
+    /**
+     * Returns an AnnotatedType object that represents the use of a type to
+     * specify the receiver type of the method/constructor represented by this
+     * Executable. The receiver type of a method/constructor is available only
+     * if the method/constructor declares a formal parameter called 'this'.
+     *
+     * Returns null if this Executable represents a constructor or instance
+     * method that either declares no formal parameter called 'this', or
+     * declares a formal parameter called 'this' with no annotations on its
+     * type.
+     *
+     * Returns null if this Executable represents a static method.
+     *
+     * @since 1.8
+     */
+    public AnnotatedType getAnnotatedReceiverType() {
+        return TypeAnnotationParser.buildAnnotatedType(getTypeAnnotationBytes(),
+                                                       sun.misc.SharedSecrets.getJavaLangAccess().
+                                                           getConstantPool(getDeclaringClass()),
+                                                       this,
+                                                       getDeclaringClass(),
+                                                       getDeclaringClass(),
+                                                       TypeAnnotation.TypeAnnotationTarget.METHOD_RECEIVER_TYPE);
+    }
+
+    /**
+     * Returns an array of AnnotatedType objects that represent the use of
+     * types to specify formal parameter types of the method/constructor
+     * represented by this Executable. The order of the objects in the array
+     * corresponds to the order of the formal parameter types in the
+     * declaration of the method/constructor.
+     *
+     * Returns an array of length 0 if the method/constructor declares no
+     * parameters.
+     *
+     * @since 1.8
+     */
+    public AnnotatedType[] getAnnotatedParameterTypes() {
+        throw new UnsupportedOperationException("Not yet");
+    }
+
+    /**
+     * Returns an array of AnnotatedType objects that represent the use of
+     * types to specify the declared exceptions of the method/constructor
+     * represented by this Executable. The order of the objects in the array
+     * corresponds to the order of the exception types in the declaration of
+     * the method/constructor.
+     *
+     * Returns an array of length 0 if the method/constructor declares no
+     * exceptions.
+     *
+     * @since 1.8
+     */
+    public AnnotatedType[] getAnnotatedExceptionTypes() {
+        return TypeAnnotationParser.buildAnnotatedTypes(getTypeAnnotationBytes(),
+                                                        sun.misc.SharedSecrets.getJavaLangAccess().
+                                                            getConstantPool(getDeclaringClass()),
+                                                        this,
+                                                        getDeclaringClass(),
+                                                        getGenericExceptionTypes(),
+                                                        TypeAnnotation.TypeAnnotationTarget.THROWS);
+    }
+
 }
--- a/src/share/classes/java/lang/reflect/Field.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/Field.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,8 @@
 import java.util.Objects;
 import sun.reflect.annotation.AnnotationParser;
 import sun.reflect.annotation.AnnotationSupport;
-
+import sun.reflect.annotation.TypeAnnotation;
+import sun.reflect.annotation.TypeAnnotationParser;
 
 /**
  * A {@code Field} provides information about, and dynamic access to, a
@@ -1020,8 +1021,7 @@
      */
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-
-        return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass);
+        return annotationClass.cast(declaredAnnotations().get(annotationClass));
     }
 
     /**
@@ -1039,7 +1039,7 @@
      * {@inheritDoc}
      */
     public Annotation[] getDeclaredAnnotations()  {
-        return AnnotationSupport.unpackToArray(declaredAnnotations());
+        return AnnotationParser.toArray(declaredAnnotations());
     }
 
     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
@@ -1053,4 +1053,20 @@
         }
         return declaredAnnotations;
     }
+
+    /**
+     * Returns an AnnotatedType object that represents the use of a type to specify
+     * the declared type of the field represented by this Field.
+     *
+     * @since 1.8
+     */
+    public AnnotatedType getAnnotatedType() {
+        return TypeAnnotationParser.buildAnnotatedType(typeAnnotations,
+                                                       sun.misc.SharedSecrets.getJavaLangAccess().
+                                                           getConstantPool(getDeclaringClass()),
+                                                       this,
+                                                       getDeclaringClass(),
+                                                       getGenericType(),
+                                                       TypeAnnotation.TypeAnnotationTarget.FIELD_TYPE);
 }
+}
--- a/src/share/classes/java/lang/reflect/Method.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/Method.java	Tue Feb 05 11:11:53 2013 -0800
@@ -165,6 +165,10 @@
     byte[] getAnnotationBytes() {
         return annotations;
     }
+    @Override
+    byte[] getTypeAnnotationBytes() {
+        return typeAnnotations;
+    }
 
     /**
      * {@inheritDoc}
@@ -621,6 +625,14 @@
         return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations);
     }
 
+    /**
+     * {@inheritDoc}
+     * @since 1.8
+     */
+    public AnnotatedType getAnnotatedReturnType() {
+        return getAnnotatedReturnType0(getGenericReturnType());
+    }
+
     @Override
     void handleParameterNumberMismatch(int resultLength, int numParameters) {
         throw new AnnotationFormatError("Parameter annotations don't match number of parameters");
--- a/src/share/classes/java/lang/reflect/Parameter.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/Parameter.java	Tue Feb 05 11:11:53 2013 -0800
@@ -233,8 +233,7 @@
      */
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-
-        return AnnotationSupport.getOneAnnotation(declaredAnnotations(), annotationClass);
+        return annotationClass.cast(declaredAnnotations().get(annotationClass));
     }
 
     /**
@@ -281,14 +280,6 @@
         return getDeclaredAnnotations();
     }
 
-    /**
-     * @throws NullPointerException {@inheritDoc}
-     */
-    public boolean isAnnotationPresent(
-        Class<? extends Annotation> annotationClass) {
-        return getAnnotation(annotationClass) != null;
-    }
-
     private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
 
     private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
--- a/src/share/classes/java/lang/reflect/ReflectAccess.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/ReflectAccess.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -128,6 +128,10 @@
         return c.getRawParameterAnnotations();
     }
 
+    public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
+        return ex.getTypeAnnotationBytes();
+    }
+
     //
     // Copying routines, needed to quickly fabricate new Field,
     // Method, and Constructor objects from templates
--- a/src/share/classes/java/lang/reflect/TypeVariable.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/lang/reflect/TypeVariable.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,4 +86,16 @@
      * @return the name of this type variable, as it appears in the source code
      */
     String getName();
+
+    /**
+     * Returns an array of AnnotatedType objects that represent the use of
+     * types to denote the upper bounds of the type parameter represented by
+     * this TypeVariable. The order of the objects in the array corresponds to
+     * the order of the bounds in the declaration of the type parameter.
+     *
+     * Returns an array of length 0 if the type parameter declares no bounds.
+     *
+     * @since 1.8
+     */
+     AnnotatedType[] getAnnotatedBounds();
 }
--- a/src/share/classes/java/math/BigDecimal.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/math/BigDecimal.java	Tue Feb 05 11:11:53 2013 -0800
@@ -3537,13 +3537,25 @@
             else
                 return expandBigIntegerTenPowers(n);
         }
-        // BigInteger.pow is slow, so make 10**n by constructing a
-        // BigInteger from a character string (still not very fast)
-        char tenpow[] = new char[n + 1];
-        tenpow[0] = '1';
-        for (int i = 1; i <= n; i++)
-            tenpow[i] = '0';
-        return new BigInteger(tenpow,1, tenpow.length);
+
+        if (n < 1024*524288) {
+            // BigInteger.pow is slow, so make 10**n by constructing a
+            // BigInteger from a character string (still not very fast)
+            // which occupies no more than 1GB (!) of memory.
+            char tenpow[] = new char[n + 1];
+            tenpow[0] = '1';
+            for (int i = 1; i <= n; i++) {
+                tenpow[i] = '0';
+            }
+            return new BigInteger(tenpow, 1, tenpow.length);
+        }
+
+        if ((n & 0x1) == 0x1) {
+            return BigInteger.TEN.multiply(bigTenToThe(n - 1));
+        } else {
+            BigInteger tmp = bigTenToThe(n/2);
+            return tmp.multiply(tmp);
+        }
     }
 
     /**
--- a/src/share/classes/java/util/Base64.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/util/Base64.java	Tue Feb 05 11:11:53 2013 -0800
@@ -64,7 +64,8 @@
  *     RFC 2045 for encoding and decoding operation. The encoded output
  *     must be represented in lines of no more than 76 characters each
  *     and uses a carriage return {@code '\r'} followed immediately by
- *     a linefeed {@code '\n'} as the line separator. All line separators
+ *     a linefeed {@code '\n'} as the line separator. No line separator
+ *     is added to the end of the encoded output. All line separators
  *     or other characters not found in the base64 alphabet table are
  *     ignored in decoding operation.</p></li>
  * </ul>
@@ -413,6 +414,7 @@
          *          specified Base64 encoded format
          */
         public OutputStream wrap(OutputStream os) {
+            Objects.requireNonNull(os);
             return new EncOutputStream(os, isURL ? toBase64URL : toBase64,
                                        newline, linemax);
         }
@@ -613,6 +615,13 @@
      * This class implements a decoder for decoding byte data using the
      * Base64 encoding scheme as specified in RFC 4648 and RFC 2045.
      *
+     * <p> The Base64 padding character {@code '='} is accepted and
+     * interpreted as the end of the encoded byte data, but is not
+     * required. So if the final unit of the encoded byte data only has
+     * two or three Base64 characters (without the corresponding padding
+     * character(s) padded), they are decoded as if followed by padding
+     * character(s).
+     *
      * <p> Instances of {@link Decoder} class are safe for use by
      * multiple concurrent threads.
      *
@@ -695,7 +704,7 @@
          * using the {@link Base64} encoding scheme.
          *
          * <p> An invocation of this method has exactly the same effect as invoking
-         * {@code return decode(src.getBytes(StandardCharsets.ISO_8859_1))}
+         * {@code decode(src.getBytes(StandardCharsets.ISO_8859_1))}
          *
          * @param   src
          *          the string to decode
@@ -856,6 +865,9 @@
         /**
          * Returns an input stream for decoding {@link Base64} encoded byte stream.
          *
+         * <p> The {@code read}  methods of the returned {@code InputStream} will
+         * throw {@code IOException} when reading bytes that cannot be decoded.
+         *
          * <p> Closing the returned input stream will close the underlying
          * input stream.
          *
@@ -866,6 +878,7 @@
          *          byte stream
          */
         public InputStream wrap(InputStream is) {
+            Objects.requireNonNull(is);
             return new DecInputStream(is, isURL ? fromBase64URL : fromBase64, isMIME);
         }
 
@@ -881,13 +894,16 @@
             int    dl = dst.arrayOffset() + dst.limit();
             int    dp0 = dp;
             int    mark = sp;
-            boolean padding = false;
             try {
                 while (sp < sl) {
                     int b = sa[sp++] & 0xff;
                     if ((b = base64[b]) < 0) {
                         if (b == -2) {   // padding byte
-                            padding = true;
+                            if (shiftto == 6 && (sp == sl || sa[sp++] != '=') ||
+                                shiftto == 18) {
+                                throw new IllegalArgumentException(
+                                     "Input byte array has wrong 4-byte ending unit");
+                            }
                             break;
                         }
                         if (isMIME)     // skip if for rfc2045
@@ -913,24 +929,23 @@
                 if (shiftto == 6) {
                     if (dl - dp < 1)
                         return dp - dp0;
-                    if (padding && (sp + 1 != sl || sa[sp++] != '='))
-                        throw new IllegalArgumentException(
-                            "Input buffer has wrong 4-byte ending unit");
                     da[dp++] = (byte)(bits >> 16);
-                    mark = sp;
                 } else if (shiftto == 0) {
                     if (dl - dp < 2)
                         return dp - dp0;
-                    if (padding && sp != sl)
-                        throw new IllegalArgumentException(
-                            "Input buffer has wrong 4-byte ending unit");
                     da[dp++] = (byte)(bits >> 16);
                     da[dp++] = (byte)(bits >>  8);
-                    mark = sp;
-                } else if (padding || shiftto != 18) {
+                } else if (shiftto == 12) {
                     throw new IllegalArgumentException(
                         "Last unit does not have enough valid bits");
                 }
+                while (sp < sl) {
+                    if (isMIME && base64[sa[sp++]] < 0)
+                        continue;
+                    throw new IllegalArgumentException(
+                        "Input byte array has incorrect ending byte at " + sp);
+                }
+                mark = sp;
                 return dp - dp0;
             } finally {
                 src.position(mark);
@@ -948,14 +963,16 @@
             int    dl = dst.limit();
             int    dp0 = dp;
             int    mark = sp;
-            boolean padding = false;
-
             try {
                 while (sp < sl) {
                     int b = src.get(sp++) & 0xff;
                     if ((b = base64[b]) < 0) {
                         if (b == -2) {  // padding byte
-                            padding = true;
+                            if (shiftto == 6 && (sp == sl || src.get(sp++) != '=') ||
+                                shiftto == 18) {
+                                throw new IllegalArgumentException(
+                                     "Input byte array has wrong 4-byte ending unit");
+                            }
                             break;
                         }
                         if (isMIME)     // skip if for rfc2045
@@ -981,24 +998,23 @@
                 if (shiftto == 6) {
                     if (dl - dp < 1)
                         return dp - dp0;
-                    if (padding && (sp + 1 != sl || src.get(sp++) != '='))
-                        throw new IllegalArgumentException(
-                            "Input buffer has wrong 4-byte ending unit");
                      dst.put(dp++, (byte)(bits >> 16));
-                     mark = sp;
                 } else if (shiftto == 0) {
                     if (dl - dp < 2)
                         return dp - dp0;
-                    if (padding && sp != sl)
-                        throw new IllegalArgumentException(
-                            "Input buffer has wrong 4-byte ending unit");
                     dst.put(dp++, (byte)(bits >> 16));
                     dst.put(dp++, (byte)(bits >>  8));
-                    mark = sp;
-                } else if (padding || shiftto != 18) {
+                } else if (shiftto == 12) {
                     throw new IllegalArgumentException(
                         "Last unit does not have enough valid bits");
                 }
+                while (sp < sl) {
+                    if (isMIME && base64[src.get(sp++)] < 0)
+                        continue;
+                    throw new IllegalArgumentException(
+                        "Input byte array has incorrect ending byte at " + sp);
+                }
+                mark = sp;
                 return dp - dp0;
             } finally {
                 src.position(mark);
@@ -1012,9 +1028,12 @@
             int len = sl - sp;
             if (len == 0)
                 return 0;
-            if (len < 2)
+            if (len < 2) {
+                if (isMIME && base64[0] == -1)
+                    return 0;
                 throw new IllegalArgumentException(
                     "Input byte[] should at least have 2 bytes for base64 bytes");
+            }
             if (src[sl - 1] == '=') {
                 paddings++;
                 if (src[sl - 2] == '=')
@@ -1043,12 +1062,20 @@
             int dp = 0;
             int bits = 0;
             int shiftto = 18;       // pos of first byte of 4-byte atom
-            boolean padding = false;
             while (sp < sl) {
                 int b = src[sp++] & 0xff;
                 if ((b = base64[b]) < 0) {
-                    if (b == -2) {     // padding byte
-                        padding = true;
+                    if (b == -2) {     // padding byte '='
+                        // xx=   shiftto==6&&sp==sl missing last =
+                        // xx=y  shiftto==6 last is not =
+                        // =     shiftto==18 unnecessary padding
+                        // x=    shiftto==12 be taken care later
+                        //       together with single x, invalid anyway
+                        if (shiftto == 6 && (sp == sl || src[sp++] != '=') ||
+                            shiftto == 18) {
+                            throw new IllegalArgumentException(
+                                "Input byte array has wrong 4-byte ending unit");
+                        }
                         break;
                     }
                     if (isMIME)    // skip if for rfc2045
@@ -1068,22 +1095,23 @@
                     bits = 0;
                 }
             }
-            // reach end of byte arry or hit padding '=' characters.
-            // if '=' presents, they must be the last one or two.
-            if (shiftto == 6) {           // xx==
-                if (padding && (sp + 1 != sl || src[sp] != '='))
-                    throw new IllegalArgumentException(
-                        "Input byte array has wrong 4-byte ending unit");
+            // reached end of byte array or hit padding '=' characters.
+            if (shiftto == 6) {
                 dst[dp++] = (byte)(bits >> 16);
-            } else if (shiftto == 0) {    // xxx=
-                if (padding && sp != sl)
-                    throw new IllegalArgumentException(
-                        "Input byte array has wrong 4-byte ending unit");
+            } else if (shiftto == 0) {
                 dst[dp++] = (byte)(bits >> 16);
                 dst[dp++] = (byte)(bits >>  8);
-            } else if (padding || shiftto != 18) {
-                    throw new IllegalArgumentException(
-                        "last unit does not have enough bytes");
+            } else if (shiftto == 12) {
+                throw new IllegalArgumentException(
+                    "Last unit does not have enough valid bits");
+            }
+            // anything left is invalid, if is not MIME.
+            // if MIME, ignore all non-base64 character
+            while (sp < sl) {
+                if (isMIME && base64[src[sp++]] < 0)
+                    continue;
+                throw new IllegalArgumentException(
+                    "Input byte array has incorrect ending byte at " + sp);
             }
             return dp;
         }
@@ -1247,8 +1275,22 @@
                 int v = is.read();
                 if (v == -1) {
                     eof = true;
-                    if (nextin != 18)
-                        throw new IOException("Base64 stream has un-decoded dangling byte(s).");
+                    if (nextin != 18) {
+                        if (nextin == 12)
+                            throw new IOException("Base64 stream has one un-decoded dangling byte.");
+                        // treat ending xx/xxx without padding character legal.
+                        // same logic as v == 'v' below
+                        b[off++] = (byte)(bits >> (16));
+                        len--;
+                        if (nextin == 0) {           // only one padding byte
+                            if (len == 0) {          // no enough output space
+                                bits >>= 8;          // shift to lowest byte
+                                nextout = 0;
+                            } else {
+                                b[off++] = (byte) (bits >>  8);
+                            }
+                        }
+                    }
                     if (off == oldOff)
                         return -1;
                     else
--- a/src/share/classes/java/util/Formatter.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/java/util/Formatter.java	Tue Feb 05 11:11:53 2013 -0800
@@ -351,7 +351,9 @@
  * <tr><td valign="top">{@code 'a'}, {@code 'A'}
  *     <td valign="top"> floating point
  *     <td> The result is formatted as a hexadecimal floating-point number with
- *     a significand and an exponent
+ *     a significand and an exponent. This conversion is <b>not</b> supported
+ *     for the {@code BigDecimal} type despite the latter's being in the
+ *     <i>floating point</i> argument category.
  *
  * <tr><td valign="top">{@code 't'}, {@code 'T'}
  *     <td valign="top"> date/time
--- a/src/share/classes/sun/management/Agent.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/management/Agent.java	Tue Feb 05 11:11:53 2013 -0800
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package sun.management;
 
 import java.io.BufferedInputStream;
@@ -31,49 +30,55 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-
+import java.lang.management.ManagementFactory;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.lang.management.ManagementFactory;
-
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
 import java.text.MessageFormat;
-
 import java.util.MissingResourceException;
 import java.util.Properties;
 import java.util.ResourceBundle;
 
 import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXServiceURL;
 
 import static sun.management.AgentConfigurationError.*;
 import sun.management.jmxremote.ConnectorBootstrap;
+import sun.management.jdp.JdpController;
+import sun.management.jdp.JdpException;
 import sun.misc.VMSupport;
 
 /**
- * This Agent is started by the VM when -Dcom.sun.management.snmp
- * or -Dcom.sun.management.jmxremote is set. This class will be
- * loaded by the system class loader. Also jmx framework could
- * be started by jcmd
+ * This Agent is started by the VM when -Dcom.sun.management.snmp or
+ * -Dcom.sun.management.jmxremote is set. This class will be loaded by the
+ * system class loader. Also jmx framework could be started by jcmd
  */
 public class Agent {
     // management properties
+
     private static Properties mgmtProps;
     private static ResourceBundle messageRB;
+    private static final String CONFIG_FILE =
+            "com.sun.management.config.file";
+    private static final String SNMP_PORT =
+            "com.sun.management.snmp.port";
+    private static final String JMXREMOTE =
+            "com.sun.management.jmxremote";
+    private static final String JMXREMOTE_PORT =
+            "com.sun.management.jmxremote.port";
+    private static final String RMI_PORT =
+            "com.sun.management.jmxremote.rmi.port";
+    private static final String ENABLE_THREAD_CONTENTION_MONITORING =
+            "com.sun.management.enableThreadContentionMonitoring";
+    private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
+            "com.sun.management.jmxremote.localConnectorAddress";
+    private static final String SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME =
+            "sun.management.snmp.AdaptorBootstrap";
 
-    private static final String CONFIG_FILE =
-        "com.sun.management.config.file";
-    private static final String SNMP_PORT =
-        "com.sun.management.snmp.port";
-    private static final String JMXREMOTE =
-        "com.sun.management.jmxremote";
-    private static final String JMXREMOTE_PORT =
-        "com.sun.management.jmxremote.port";
-    private static final String ENABLE_THREAD_CONTENTION_MONITORING =
-        "com.sun.management.enableThreadContentionMonitoring";
-    private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
-        "com.sun.management.jmxremote.localConnectorAddress";
-
-    private static final String SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME =
-        "sun.management.snmp.AdaptorBootstrap";
+    private static final String JDP_DEFAULT_ADDRESS = "239.255.255.225";
+    private static final int JDP_DEFAULT_PORT = 7095;
 
     // The only active agent allowed
     private static JMXConnectorServer jmxServer = null;
@@ -81,26 +86,25 @@
     // Parse string com.sun.management.prop=xxx,com.sun.management.prop=yyyy
     // and return property set if args is null or empty
     // return empty property set
-    private static Properties parseString(String args){
+    private static Properties parseString(String args) {
         Properties argProps = new Properties();
         if (args != null) {
-           for (String option : args.split(",")) {
-               String s[] = option.split("=", 2);
-               String name = s[0].trim();
-               String value = (s.length > 1) ? s[1].trim() : "";
+            for (String option : args.split(",")) {
+                String s[] = option.split("=", 2);
+                String name = s[0].trim();
+                String value = (s.length > 1) ? s[1].trim() : "";
 
-               if (!name.startsWith("com.sun.management.")) {
-                  error(INVALID_OPTION, name);
-               }
+                if (!name.startsWith("com.sun.management.")) {
+                    error(INVALID_OPTION, name);
+                }
 
-               argProps.setProperty(name, value);
-           }
+                argProps.setProperty(name, value);
+            }
         }
 
         return argProps;
     }
 
-
     // invoked by -javaagent or -Dcom.sun.management.agent.class
     public static void premain(String args) throws Exception {
         agentmain(args);
@@ -115,18 +119,18 @@
         Properties arg_props = parseString(args);
 
         // Read properties from the config file
-         Properties config_props = new Properties();
-         String fname = arg_props.getProperty(CONFIG_FILE);
-         readConfiguration(fname, config_props);
+        Properties config_props = new Properties();
+        String fname = arg_props.getProperty(CONFIG_FILE);
+        readConfiguration(fname, config_props);
 
-         // Arguments override config file
-         config_props.putAll(arg_props);
-         startAgent(config_props);
+        // Arguments override config file
+        config_props.putAll(arg_props);
+        startAgent(config_props);
     }
 
     // jcmd ManagementAgent.start_local entry point
     // Also called due to command-line via startAgent()
-    private static synchronized void startLocalManagementAgent(){
+    private static synchronized void startLocalManagementAgent() {
         Properties agentProps = VMSupport.getAgentProperties();
 
         // start local connector if not started
@@ -156,7 +160,7 @@
             throw new RuntimeException(getText(INVALID_STATE, "Agent already started"));
         }
 
-        Properties argProps    = parseString(args);
+        Properties argProps = parseString(args);
         Properties configProps = new Properties();
 
         // Load the management properties from the config file
@@ -169,7 +173,7 @@
         // management properties can be overridden by system properties
         // which take precedence
         Properties sysProps = System.getProperties();
-        synchronized(sysProps){
+        synchronized (sysProps) {
             configProps.putAll(sysProps);
         }
 
@@ -190,21 +194,26 @@
         // can specify this property inside config file, so enable optional
         // monitoring functionality if this property is set
         final String enableThreadContentionMonitoring =
-            configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
+                configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
 
         if (enableThreadContentionMonitoring != null) {
             ManagementFactory.getThreadMXBean().
-                setThreadContentionMonitoringEnabled(true);
+                    setThreadContentionMonitoringEnabled(true);
         }
 
         String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT);
         if (jmxremotePort != null) {
             jmxServer = ConnectorBootstrap.
-                           startRemoteConnectorServer(jmxremotePort, configProps);
+                    startRemoteConnectorServer(jmxremotePort, configProps);
+
+            startDiscoveryService(configProps);
         }
     }
 
     private static synchronized void stopRemoteManagementAgent() throws Exception {
+
+        JdpController.stopDiscoveryService();
+
         if (jmxServer != null) {
             ConnectorBootstrap.unexportRegistry();
 
@@ -222,15 +231,15 @@
 
         // Enable optional monitoring functionality if requested
         final String enableThreadContentionMonitoring =
-            props.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
+                props.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
         if (enableThreadContentionMonitoring != null) {
             ManagementFactory.getThreadMXBean().
-                setThreadContentionMonitoringEnabled(true);
+                    setThreadContentionMonitoringEnabled(true);
         }
 
         try {
             if (snmpPort != null) {
-               loadSnmpAgent(snmpPort, props);
+                loadSnmpAgent(snmpPort, props);
             }
 
             /*
@@ -242,13 +251,14 @@
              * of this "local" server is exported as a counter to the jstat
              * instrumentation buffer.
              */
-             if (jmxremote != null || jmxremotePort != null) {
+            if (jmxremote != null || jmxremotePort != null) {
                 if (jmxremotePort != null) {
-                   jmxServer = ConnectorBootstrap.
-                               startRemoteConnectorServer(jmxremotePort, props);
+                    jmxServer = ConnectorBootstrap.
+                            startRemoteConnectorServer(jmxremotePort, props);
+                    startDiscoveryService(props);
                 }
                 startLocalManagementAgent();
-             }
+            }
 
         } catch (AgentConfigurationError e) {
             error(e.getError(), e.getParams());
@@ -257,6 +267,73 @@
         }
     }
 
+    private static void startDiscoveryService(Properties props)
+            throws IOException {
+        // Start discovery service if requested
+        String discoveryPort = props.getProperty("com.sun.management.jdp.port");
+        String discoveryAddress = props.getProperty("com.sun.management.jdp.address");
+        String discoveryShouldStart = props.getProperty("com.sun.management.jmxremote.autodiscovery");
+
+        // Decide whether we should start autodicovery service.
+        // To start autodiscovery following conditions should be met:
+        // autodiscovery==true OR (autodicovery==null AND jdp.port != NULL)
+
+        boolean shouldStart = false;
+        if (discoveryShouldStart == null){
+            shouldStart = (discoveryPort != null);
+        }
+        else{
+            try{
+               shouldStart = Boolean.parseBoolean(discoveryShouldStart);
+            } catch (NumberFormatException e) {
+                throw new AgentConfigurationError("Couldn't parse autodiscovery argument");
+            }
+        }
+
+        if (shouldStart) {
+            // port and address are required arguments and have no default values
+            InetAddress address;
+            try {
+                address = (discoveryAddress == null) ?
+                        InetAddress.getByName(JDP_DEFAULT_ADDRESS) : InetAddress.getByName(discoveryAddress);
+            } catch (UnknownHostException e) {
+                throw new AgentConfigurationError("Unable to broadcast to requested address", e);
+            }
+
+            int port = JDP_DEFAULT_PORT;
+            if (discoveryPort != null) {
+               try {
+                  port = Integer.parseInt(discoveryPort);
+               } catch (NumberFormatException e) {
+                 throw new AgentConfigurationError("Couldn't parse JDP port argument");
+               }
+            }
+
+            // Rebuilding service URL to broadcast it
+            String jmxremotePort = props.getProperty(JMXREMOTE_PORT);
+            String rmiPort = props.getProperty(RMI_PORT);
+
+            JMXServiceURL url = jmxServer.getAddress();
+            String hostname = url.getHost();
+
+            String jmxUrlStr = (rmiPort != null)
+                    ? String.format(
+                    "service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi",
+                    hostname, rmiPort, hostname, jmxremotePort)
+                    : String.format(
+                    "service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", hostname, jmxremotePort);
+
+            String instanceName = System.getProperty("com.sun.management.jdp.name");
+
+            try{
+               JdpController.startDiscoveryService(address, port, instanceName, jmxUrlStr);
+            }
+            catch(JdpException e){
+                throw new AgentConfigurationError("Couldn't start JDP service", e);
+            }
+        }
+    }
+
     public static Properties loadManagementProperties() {
         Properties props = new Properties();
 
@@ -268,22 +345,22 @@
         // management properties can be overridden by system properties
         // which take precedence
         Properties sysProps = System.getProperties();
-        synchronized(sysProps){
+        synchronized (sysProps) {
             props.putAll(sysProps);
         }
 
         return props;
-   }
+    }
 
-   public static synchronized Properties getManagementProperties() {
+    public static synchronized Properties getManagementProperties() {
         if (mgmtProps == null) {
             String configFile = System.getProperty(CONFIG_FILE);
             String snmpPort = System.getProperty(SNMP_PORT);
             String jmxremote = System.getProperty(JMXREMOTE);
             String jmxremotePort = System.getProperty(JMXREMOTE_PORT);
 
-            if (configFile == null && snmpPort == null &&
-                jmxremote == null && jmxremotePort == null) {
+            if (configFile == null && snmpPort == null
+                    && jmxremote == null && jmxremotePort == null) {
                 // return if out-of-the-management option is not specified
                 return null;
             }
@@ -297,22 +374,23 @@
             // invoke the following through reflection:
             //     AdaptorBootstrap.initialize(snmpPort, props);
             final Class<?> adaptorClass =
-                Class.forName(SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME,true,null);
+                    Class.forName(SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME, true, null);
             final Method initializeMethod =
                     adaptorClass.getMethod("initialize",
-                        String.class, Properties.class);
-            initializeMethod.invoke(null,snmpPort,props);
+                    String.class, Properties.class);
+            initializeMethod.invoke(null, snmpPort, props);
         } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException x) {
             // snmp runtime doesn't exist - initialization fails
-            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,x);
+            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, x);
         } catch (InvocationTargetException x) {
             final Throwable cause = x.getCause();
-            if (cause instanceof RuntimeException)
+            if (cause instanceof RuntimeException) {
                 throw (RuntimeException) cause;
-            else if (cause instanceof Error)
+            } else if (cause instanceof Error) {
                 throw (Error) cause;
+            }
             // should not happen...
-            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT,cause);
+            throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT, cause);
         }
     }
 
@@ -353,8 +431,8 @@
                 } catch (IOException e) {
                     error(CONFIG_FILE_CLOSE_FAILED, fname);
                 }
-             }
-         }
+            }
+        }
     }
 
     public static void startAgent() throws Exception {
@@ -389,9 +467,9 @@
                 // invoke the premain(String args) method
                 Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname);
                 Method premain = clz.getMethod("premain",
-                                               new Class<?>[] { String.class });
+                        new Class<?>[]{String.class});
                 premain.invoke(null, /* static */
-                               new Object[] { args });
+                        new Object[]{args});
             } catch (ClassNotFoundException ex) {
                 error(AGENT_CLASS_NOT_FOUND, "\"" + cname + "\"");
             } catch (NoSuchMethodException ex) {
@@ -400,8 +478,8 @@
                 error(AGENT_CLASS_ACCESS_DENIED);
             } catch (Exception ex) {
                 String msg = (ex.getCause() == null
-                                 ? ex.getMessage()
-                                 : ex.getCause().getMessage());
+                        ? ex.getMessage()
+                        : ex.getCause().getMessage());
                 error(AGENT_CLASS_FAILED, msg);
             }
         }
@@ -425,7 +503,6 @@
         }
     }
 
-
     public static void error(String key, String message) {
         String keyText = getText(key);
         System.err.print(getText("agent.err.error") + ": " + keyText);
@@ -447,7 +524,7 @@
     private static void initResource() {
         try {
             messageRB =
-                ResourceBundle.getBundle("sun.management.resources.agent");
+                    ResourceBundle.getBundle("sun.management.resources.agent");
         } catch (MissingResourceException e) {
             throw new Error("Fatal: Resource for management agent is missing");
         }
@@ -470,10 +547,9 @@
         }
         String format = messageRB.getString(key);
         if (format == null) {
-            format = "missing resource key: key = \"" + key + "\", " +
-                "arguments = \"{0}\", \"{1}\", \"{2}\"";
+            format = "missing resource key: key = \"" + key + "\", "
+                    + "arguments = \"{0}\", \"{1}\", \"{2}\"";
         }
         return MessageFormat.format(format, (Object[]) args);
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpBroadcaster.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.IOException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.ProtocolFamily;
+import java.net.StandardProtocolFamily;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.UnsupportedAddressTypeException;
+
+/**
+ * JdpBroadcaster is responsible for sending pre-built JDP packet across a Net
+ *
+ * <p> Multicast group address, port number and ttl have to be chosen on upper
+ * level and passed to broadcaster constructor. Also it's possible to specify
+ * source address to broadcast from. </p>
+ *
+ * <p>JdpBradcaster doesn't perform any validation on a supplied {@code port} and {@code ttl} because
+ * the allowed values depend on an operating system setup</p>
+ *
+ */
+public final class JdpBroadcaster {
+
+    private final InetAddress addr;
+    private final int port;
+    private final DatagramChannel channel;
+
+    /**
+     * Create a new broadcaster
+     *
+     * @param address - multicast group address
+     * @param srcAddress - address of interface we should use to broadcast.
+     * @param port - udp port to use
+     * @param ttl - packet ttl
+     * @throws IOException
+     */
+    public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
+            throws IOException, JdpException {
+        this.addr = address;
+        this.port = port;
+
+        ProtocolFamily family = (address instanceof Inet6Address)
+                ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
+
+        channel = DatagramChannel.open(family);
+        channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
+        channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
+
+        // with srcAddress equal to null, this constructor do exactly the same as
+        // if srcAddress is not passed
+        if (srcAddress != null) {
+            // User requests particular interface to bind to
+            NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
+            try {
+                channel.bind(new InetSocketAddress(srcAddress, 0));
+            } catch (UnsupportedAddressTypeException ex) {
+                throw new JdpException("Unable to bind to source address");
+            }
+            channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
+        }
+    }
+
+    /**
+     * Create a new broadcaster
+     *
+     * @param address - multicast group address
+     * @param port - udp port to use
+     * @param ttl - packet ttl
+     * @throws IOException
+     */
+    public JdpBroadcaster(InetAddress address, int port, int ttl)
+            throws IOException, JdpException {
+        this(address, null, port, ttl);
+    }
+
+    /**
+     * Broadcast pre-built packet
+     *
+     * @param packet - instance of JdpPacket
+     * @throws IOException
+     */
+    public void sendPacket(JdpPacket packet)
+            throws IOException {
+        byte[] data = packet.getPacketData();
+        // Unlike allocate/put wrap don't need a flip afterward
+        ByteBuffer b = ByteBuffer.wrap(data);
+        channel.send(b, new InetSocketAddress(addr, port));
+    }
+
+    /**
+     * Shutdown broadcaster and close underlying socket channel
+     *
+     * @throws IOException
+     */
+    public void shutdown() throws IOException {
+        channel.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpController.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,196 @@
+/*
+ * 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 sun.management.jdp;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.UUID;
+
+/**
+ * JdpController is responsible to create and manage a broadcast loop
+ *
+ * <p> Other part of code has no access to broadcast loop and have to use
+ * provided static methods
+ * {@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService}
+ * and {@link #stopDiscoveryService() stopDiscoveryService}</p>
+ * <p>{@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService} could be called multiple
+ * times as it stops the running service if it is necessary. Call to {@link #stopDiscoveryService() stopDiscoveryService}
+ * ignored if service isn't run</p>
+ *
+ *
+ * </p>
+ *
+ * <p> System properties below could be used to control broadcast loop behavior.
+ * Property below have to be set explicitly in command line. It's not possible to
+ * set it in management.config file.  Careless changes of these properties could
+ * lead to security or network issues.
+ * <ul>
+ *     <li>com.sun.management.jdp.ttl         - set ttl for broadcast packet</li>
+ *     <li>com.sun.management.jdp.pause       - set broadcast interval in seconds</li>
+ *     <li>com.sun.management.jdp.source_addr - an address of interface to use for broadcast</li>
+ * </ul>
+  </p>
+ * <p>null parameters values are filtered out on {@link JdpPacketWriter} level and
+ * corresponding keys are not placed to packet.</p>
+ */
+public final class JdpController {
+
+    private static class JDPControllerRunner implements Runnable {
+
+        private final JdpJmxPacket packet;
+        private final JdpBroadcaster bcast;
+        private final int pause;
+        private volatile boolean shutdown = false;
+
+        private JDPControllerRunner(JdpBroadcaster bcast, JdpJmxPacket packet, int pause) {
+            this.bcast = bcast;
+            this.packet = packet;
+            this.pause = pause;
+        }
+
+        @Override
+        public void run() {
+            try {
+                while (!shutdown) {
+                    bcast.sendPacket(packet);
+                    try {
+                        Thread.sleep(this.pause);
+                    } catch (InterruptedException e) {
+                        // pass
+                    }
+                }
+
+            } catch (IOException e) {
+              // pass;
+            }
+
+            // It's not possible to re-use controller,
+            // nevertheless reset shutdown variable
+            try {
+                stop();
+                bcast.shutdown();
+            } catch (IOException ex) {
+                // pass - ignore IOException during shutdown
+            }
+        }
+
+        public void stop() {
+            shutdown = true;
+        }
+    }
+    private static JDPControllerRunner controller = null;
+
+    private JdpController(){
+        // Don't allow to instantiate this class.
+    }
+
+    // Utility to handle optional system properties
+    // Parse an integer from string or return default if provided string is null
+    private static int getInteger(String val, int dflt, String msg) throws JdpException {
+        try {
+            return (val == null) ? dflt : Integer.parseInt(val);
+        } catch (NumberFormatException ex) {
+            throw new JdpException(msg);
+        }
+    }
+
+    // Parse an inet address from string or return default if provided string is null
+    private static InetAddress getInetAddress(String val, InetAddress dflt, String msg) throws JdpException {
+        try {
+            return (val == null) ? dflt : InetAddress.getByName(val);
+        } catch (UnknownHostException ex) {
+            throw new JdpException(msg);
+        }
+    }
+
+    /**
+     * Starts discovery service
+     *
+     * @param address - multicast group address
+     * @param port - udp port to use
+     * @param instanceName - name of running JVM instance
+     * @param url - JMX service url
+     * @throws IOException
+     */
+    public static synchronized void startDiscoveryService(InetAddress address, int port, String instanceName, String url)
+            throws IOException, JdpException {
+
+        // Limit packet to local subnet by default
+        int ttl = getInteger(
+                System.getProperty("com.sun.management.jdp.ttl"), 1,
+                "Invalid jdp packet ttl");
+
+        // Broadcast once a 5 seconds by default
+        int pause = getInteger(
+                System.getProperty("com.sun.management.jdp.pause"), 5,
+                "Invalid jdp pause");
+
+        // Converting seconds to milliseconds
+        pause = pause * 1000;
+
+        // Allow OS to choose broadcast source
+        InetAddress sourceAddress = getInetAddress(
+                System.getProperty("com.sun.management.jdp.source_addr"), null,
+                "Invalid source address provided");
+
+        // Generate session id
+        UUID id = UUID.randomUUID();
+
+        JdpJmxPacket packet = new JdpJmxPacket(id, url);
+
+        // Don't broadcast whole command line for security reason.
+        // Strip everything after first space
+        String javaCommand = System.getProperty("sun.java.command");
+        if (javaCommand != null) {
+            String[] arr = javaCommand.split(" ", 2);
+            packet.setMainClass(arr[0]);
+        }
+
+        // Put optional explicit java instance name to packet, if user doesn't specify
+        // it the key is skipped. PacketWriter is responsible to skip keys having null value.
+        packet.setInstanceName(instanceName);
+
+        JdpBroadcaster bcast = new JdpBroadcaster(address, sourceAddress, port, ttl);
+
+        // Stop discovery service if it's already running
+        stopDiscoveryService();
+
+        controller = new JDPControllerRunner(bcast, packet, pause);
+
+        Thread t = new Thread(controller, "JDP broadcaster");
+        t.setDaemon(true);
+        t.start();
+    }
+
+    /**
+     * Stop running discovery service,
+     * it's safe to attempt to stop not started service
+     */
+    public static synchronized void stopDiscoveryService() {
+        if ( controller != null ){
+             controller.stop();
+             controller = null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpException.java	Tue Feb 05 11:11:53 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 sun.management.jdp;
+
+/**
+ * An Exception thrown if a JDP implementation encounters a problem.
+ */
+public final class JdpException extends Exception {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Construct a new JDP exception with a meaningful message
+     *
+     * @param msg - message
+     */
+    public JdpException(String msg) {
+        super(msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpGenericPacket.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,95 @@
+/*
+ * 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 sun.management.jdp;
+
+/**
+ * JdpGenericPacket responsible to provide fields
+ * common for all Jdp packets
+ */
+public abstract class JdpGenericPacket implements JdpPacket {
+
+    /**
+     * JDP protocol magic. Magic allows a reader to quickly select
+     * JDP packets from a bunch of broadcast packets addressed to the same port
+     * and broadcast group. Any packet intended to be parsed by JDP client
+     * has to start from this  magic.
+     */
+    private static final int MAGIC = 0xC0FFEE42;
+
+    /**
+     * Current version of protocol. Any implementation of this protocol has to
+     * conform with the packet structure and the flow described in JEP-168
+     */
+    private static final short PROTOCOL_VERSION = 1;
+
+    /**
+     * Default do-nothing constructor
+     */
+    protected  JdpGenericPacket(){
+        // do nothing
+    }
+
+
+    /**
+     * Validate protocol header magic field
+     *
+     * @param magic - value to validate
+     * @throws JdpException
+     */
+    public static void checkMagic(int magic)
+            throws JdpException {
+        if (magic != MAGIC) {
+            throw new JdpException("Invalid JDP magic header: " + magic);
+        }
+    }
+
+    /**
+     * Validate protocol header version field
+     *
+     * @param version - value to validate
+     * @throws JdpException
+     */
+    public static void checkVersion(short version)
+            throws JdpException {
+
+        if (version > PROTOCOL_VERSION) {
+            throw new JdpException("Unsupported protocol version: " + version);
+        }
+    }
+
+    /**
+     *
+     * @return protocol magic
+     */
+    public static int getMagic() {
+        return MAGIC;
+    }
+
+    /**
+     *
+     * @return current protocol version
+     */
+    public static short getVersion() {
+        return PROTOCOL_VERSION;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpJmxPacket.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,196 @@
+/*
+ * 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 sun.management.jdp;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * A packet to broadcasts JMX URL
+ *
+ * Fields:
+ *
+ * <ul>
+ * <li>UUID - broadcast session ID, changed every time when we start/stop
+ * discovery service</li>
+ * <li>JMX_URL - URL to connect to JMX service</li>
+ * <li>MAIN_CLASS - optional name of main class, filled from sun.java.command stripped for
+ * security reason to first space</li>
+ * <li>INSTANCE_NAME - optional custom name of particular instance as provided by customer</li>
+ * </ul>
+ */
+public final class JdpJmxPacket
+       extends JdpGenericPacket
+       implements JdpPacket {
+
+    /**
+     * Session ID
+     */
+    public final static String UUID_KEY = "DISCOVERABLE_SESSION_UUID";
+    /**
+     * Name of main class
+     */
+    public final static String MAIN_CLASS_KEY = "MAIN_CLASS";
+    /**
+     * JMX service URL
+     */
+    public final static String JMX_SERVICE_URL_KEY = "JMX_SERVICE_URL";
+    /**
+     * Name of Java instance
+     */
+    public final static String INSTANCE_NAME_KEY = "INSTANCE_NAME";
+
+    private UUID id;
+    private String mainClass;
+    private String jmxServiceUrl;
+    private String instanceName;
+
+    /**
+     * Create new instance from user provided data. Set mandatory fields
+     *
+     * @param id - java instance id
+     * @param jmxServiceUrl - JMX service url
+     */
+    public JdpJmxPacket(UUID id, String jmxServiceUrl) {
+        this.id = id;
+        this.jmxServiceUrl = jmxServiceUrl;
+    }
+
+    /**
+     * Create new instance from network data Parse packet and set fields.
+     *
+     * @param data - raw packet data as it came from a Net
+     * @throws JdpException
+     */
+    public JdpJmxPacket(byte[] data)
+            throws JdpException {
+        JdpPacketReader reader;
+
+        reader = new JdpPacketReader(data);
+        Map<String, String> p = reader.getDiscoveryDataAsMap();
+
+        String sId = p.get(UUID_KEY);
+        this.id = (sId == null) ? null : UUID.fromString(sId);
+        this.jmxServiceUrl = p.get(JMX_SERVICE_URL_KEY);
+        this.mainClass = p.get(MAIN_CLASS_KEY);
+        this.instanceName = p.get(INSTANCE_NAME_KEY);
+    }
+
+    /**
+     * Set main class field
+     *
+     * @param mainClass - main class of running app
+     */
+    public void setMainClass(String mainClass) {
+        this.mainClass = mainClass;
+    }
+
+    /**
+     * Set instance name field
+     *
+     * @param instanceName - name of instance as provided by customer
+     */
+    public void setInstanceName(String instanceName) {
+        this.instanceName = instanceName;
+    }
+
+    /**
+     * @return id of discovery session
+     */
+    public UUID getId() {
+        return id;
+    }
+
+    /**
+     *
+     * @return main class field
+     */
+    public String getMainClass() {
+        return mainClass;
+    }
+
+    /**
+     *
+     * @return JMX service URL
+     */
+    public String getJmxServiceUrl() {
+        return jmxServiceUrl;
+    }
+
+    /**
+     *
+     * @return instance name
+     */
+    public String getInstanceName() {
+        return instanceName;
+    }
+
+    /**
+     *
+     * @return assembled packet ready to be sent across a Net
+     * @throws IOException
+     */
+    @Override
+    public byte[] getPacketData() throws IOException {
+        // Assemble packet from fields to byte array
+        JdpPacketWriter writer;
+        writer = new JdpPacketWriter();
+        writer.addEntry(UUID_KEY, (id == null) ? null : id.toString());
+        writer.addEntry(MAIN_CLASS_KEY, mainClass);
+        writer.addEntry(JMX_SERVICE_URL_KEY, jmxServiceUrl);
+        writer.addEntry(INSTANCE_NAME_KEY, instanceName);
+        return writer.getPacketBytes();
+    }
+
+    /**
+     *
+     * @return packet hash code
+     */
+    @Override
+    public int hashCode() {
+        int hash = 1;
+        hash = hash * 31 + id.hashCode();
+        hash = hash * 31 + jmxServiceUrl.hashCode();
+        return hash;
+    }
+
+    /**
+     * Compare two packets
+     *
+     * @param o - packet to compare
+     * @return either packet equals or not
+     */
+    @Override
+    public boolean equals(Object o) {
+
+        if (o == null || ! (o instanceof JdpJmxPacket) ){
+            return false;
+        }
+
+        JdpJmxPacket p = (JdpJmxPacket) o;
+        return  Objects.equals(id, p.getId()) && Objects.equals(jmxServiceUrl, p.getJmxServiceUrl());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpPacket.java	Tue Feb 05 11:11:53 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.management.jdp;
+
+import java.io.IOException;
+
+/**
+ * Packet to broadcast
+ *
+ * <p>Each packet have to contain MAGIC and PROTOCOL_VERSION in order to be
+ * recognized as a valid JDP packet.</p>
+ *
+ * <p>Default implementation build packet as a set of UTF-8 encoded Key/Value pairs
+ * are stored as an ordered list of values, and are sent to the server
+ * in that order.</p>
+ *
+ * <p>
+ * Packet structure:
+ *
+ * 4 bytes JDP magic (0xC0FFE42)
+ * 2 bytes JDP protocol version (01)
+ *
+ * 2 bytes size of key
+ * x bytes key (UTF-8 encoded)
+ * 2 bytes size of value
+ * x bytes value (UTF-8 encoded)
+ *
+ * repeat as many times as necessary ...
+ * </p>
+  */
+public interface JdpPacket {
+
+    /**
+     * This method responsible to assemble packet and return a byte array
+     * ready to be sent across a Net.
+     *
+     * @return assembled packet as an array of bytes
+     * @throws IOException
+     */
+    public byte[] getPacketData() throws IOException;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpPacketReader.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,139 @@
+/*
+ * 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 sun.management.jdp;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JdpPacketReader responsible for reading a packet <p>This class gets a byte
+ * array as it came from a Net, validates it and breaks a part </p>
+ */
+public final class JdpPacketReader {
+
+    private final DataInputStream pkt;
+    private Map<String, String> pmap = null;
+
+    /**
+     * Create packet reader, extract and check magic and version
+     *
+     * @param packet - packet received from a Net
+     * @throws JdpException
+     */
+    public JdpPacketReader(byte[] packet)
+            throws JdpException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(packet);
+        pkt = new DataInputStream(bais);
+
+        try {
+            int magic = pkt.readInt();
+            JdpGenericPacket.checkMagic(magic);
+        } catch (IOException e) {
+            throw new JdpException("Invalid JDP packet received, bad magic");
+        }
+
+        try {
+            short version = pkt.readShort();
+            JdpGenericPacket.checkVersion(version);
+        } catch (IOException e) {
+            throw new JdpException("Invalid JDP packet received, bad protocol version");
+        }
+    }
+
+    /**
+     * Get next entry from packet
+     *
+     * @return the entry
+     * @throws EOFException
+     * @throws JdpException
+     */
+    public String getEntry()
+            throws EOFException, JdpException {
+
+        try {
+            short len = pkt.readShort();
+            // Artificial setting the "len" field to Short.MAX_VALUE may cause a reader to allocate
+            // to much memory. Prevent this possible DOS attack.
+            if (len < 1 && len > pkt.available()) {
+                throw new JdpException("Broken JDP packet. Invalid entry length field.");
+            }
+
+            byte[] b = new byte[len];
+            if (pkt.read(b) != len) {
+                throw new JdpException("Broken JDP packet. Unable to read entry.");
+            }
+            return new String(b, "UTF-8");
+
+        } catch (EOFException e) {
+            throw e;
+        } catch (UnsupportedEncodingException ex) {
+            throw new JdpException("Broken JDP packet. Unable to decode entry.");
+        } catch (IOException e) {
+            throw new JdpException("Broken JDP packet. Unable to read entry.");
+        }
+
+
+    }
+
+    /**
+     * return packet content as a key/value map
+     *
+     * @return map containing packet entries pair of entries treated as
+     * key,value
+     * @throws IOException
+     * @throws JdpException
+     */
+    public Map<String, String> getDiscoveryDataAsMap()
+            throws JdpException {
+        // return cached map if possible
+        if (pmap != null) {
+            return pmap;
+        }
+
+        String key = null, value = null;
+
+        final Map<String, String> tmpMap = new HashMap<>();
+        try {
+            while (true) {
+                key = getEntry();
+                value = getEntry();
+                tmpMap.put(key, value);
+            }
+        } catch (EOFException e) {
+            // EOF reached on reading value, report broken packet
+            // otherwise ignore it.
+            if (value == null) {
+                throw new JdpException("Broken JDP packet. Key without value." + key);
+            }
+        }
+
+        pmap = Collections.unmodifiableMap(tmpMap);
+        return pmap;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/JdpPacketWriter.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * JdpPacketWriter responsible for writing a packet
+ * <p>This class assembles a set of key/value pairs to valid JDP packet,
+ * ready to be sent across a Net</p>
+ */
+public final class JdpPacketWriter {
+
+    private final ByteArrayOutputStream baos;
+    private final DataOutputStream pkt;
+
+    /**
+     * Create a JDP packet, add mandatory magic and version headers
+     *
+     * @throws IOException
+     */
+    public JdpPacketWriter()
+            throws IOException {
+        baos = new ByteArrayOutputStream();
+        pkt = new DataOutputStream(baos);
+
+        pkt.writeInt(JdpGenericPacket.getMagic());
+        pkt.writeShort(JdpGenericPacket.getVersion());
+    }
+
+    /**
+     * Put string entry to packet
+     *
+     * @param entry - string to put (utf-8 encoded)
+     * @throws IOException
+     */
+    public void addEntry(String entry)
+            throws IOException {
+        pkt.writeShort(entry.length());
+        byte[] b = entry.getBytes("UTF-8");
+        pkt.write(b);
+    }
+
+    /**
+     * Put key/value pair to packet
+     *
+     * @param key - key to put (utf-8 encoded)
+     * @param val - value to put (utf-8 encoded)
+     * @throws IOException
+     */
+    public void addEntry(String key, String val)
+            throws IOException {
+        /* Silently skip key if value is null.
+         * We don't need to distinguish between key missing
+         * and key has no value cases
+         */
+        if (val != null) {
+            addEntry(key);
+            addEntry(val);
+        }
+    }
+
+    /**
+     * Return assembled packet as a byte array
+     *
+     * @return packet bytes
+     */
+    public byte[] getPacketBytes() {
+        return baos.toByteArray();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/management/jdp/package-info.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,55 @@
+/**
+ *  Summary
+ *  -------
+ *
+ *  Define a lightweight network protocol for discovering running and
+ *  manageable Java processes within a network subnet.
+ *
+ *
+ * Description
+ * -----------
+ *
+ * The protocol is lightweight multicast based, and works like a beacon,
+ * broadcasting the JMXService URL needed to connect to the external JMX
+ * agent if an application is started with appropriate parameters.
+ *
+ * The payload is structured like this:
+ *
+ *  4 bytes JDP magic (0xC0FFEE42)
+ *  2 bytes JDP protocol version (1)
+ *  2 bytes size of the next entry
+ *      x bytes next entry (UTF-8 encoded)
+ *  2 bytes size of next entry
+ *    ...   Rinse and repeat...
+ *
+ * The payload will be parsed as even entries being keys, odd entries being
+ * values.
+ *
+ * The standard JDP packet contains four entries:
+ *
+ * - `DISCOVERABLE_SESSION_UUID` -- Unique id of the instance; this id changes every time
+ *    the discovery protocol starts and stops
+ *
+ * - `MAIN_CLASS` -- The value of the `sun.java.command` property
+ *
+ * - `JMX_SERVICE_URL` -- The URL to connect to the JMX agent
+ *
+ * - `INSTANCE_NAME` -- The user-provided name of the running instance
+ *
+ * The protocol sends packets to 239.255.255.225:7095 by default.
+ *
+ * The protocol uses system properties to control it's behaviour:
+ * - `com.sun.management.jdp.port` -- override default port
+ *
+ * - `com.sun.management.jdp.address` -- override default address
+ *
+ * - `com.sun.management.jmxremote.autodiscovery` -- whether we should start autodiscovery or
+ * not. Autodiscovery starts if and only if following conditions are met: (autodiscovery is
+ * true OR (autodiscovery is not set AND jdp.port is set))
+ *
+ * - `com.sun.management.jdp.ttl`         -- set ttl for broadcast packet, default is 1
+ * - `com.sun.management.jdp.pause`       -- set broadcast interval in seconds default is 5
+ * - `com.sun.management.jdp.source_addr` -- an address of interface to use for broadcast
+ */
+
+package sun.management.jdp;
--- a/src/share/classes/sun/misc/JavaLangAccess.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/misc/JavaLangAccess.java	Tue Feb 05 11:11:53 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
@@ -26,6 +26,7 @@
 package sun.misc;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Executable;
 import sun.reflect.ConstantPool;
 import sun.reflect.annotation.AnnotationType;
 import sun.nio.ch.Interruptible;
@@ -47,6 +48,18 @@
     AnnotationType getAnnotationType(Class<?> klass);
 
     /**
+     * Get the array of bytes that is the class-file representation
+     * of this Class' type annotations.
+     */
+    byte[] getRawClassTypeAnnotations(Class<?> klass);
+
+    /**
+     * Get the array of bytes that is the class-file representation
+     * of this Executable's type annotations.
+     */
+    byte[] getRawExecutableTypeAnnotations(Executable executable);
+
+    /**
      * Returns the elements of an enum class or null if the
      * Class object does not represent an enum type;
      * the result is uncloned, cached, and shared by all callers.
@@ -84,9 +97,4 @@
      * Returns the ith StackTraceElement for the given throwable.
      */
     StackTraceElement getStackTraceElement(Throwable t, int i);
-
-    /**
-     * Returns a directly present annotation.
-     */
-    public <A extends Annotation> A getDirectDeclaredAnnotation(Class<?> klass, Class<A> anno);
 }
--- a/src/share/classes/sun/reflect/LangReflectAccess.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/reflect/LangReflectAccess.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -81,6 +81,9 @@
     public void setConstructorAccessor(Constructor<?> c,
                                        ConstructorAccessor accessor);
 
+    /** Gets the byte[] that encodes TypeAnnotations on an Executable. */
+    public byte[] getExecutableTypeAnnotationBytes(Executable ex);
+
     /** Gets the "slot" field from a Constructor (used for serialization) */
     public int getConstructorSlot(Constructor<?> c);
 
--- a/src/share/classes/sun/reflect/ReflectionFactory.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/reflect/ReflectionFactory.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package sun.reflect;
 
 import java.lang.reflect.Field;
+import java.lang.reflect.Executable;
 import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
@@ -314,6 +315,12 @@
         return langReflectAccess().copyConstructor(arg);
     }
 
+    /** Gets the byte[] that encodes TypeAnnotations on an executable.
+     */
+    public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
+        return langReflectAccess().getExecutableTypeAnnotationBytes(ex);
+    }
+
     //--------------------------------------------------------------------------
     //
     // Routines used by serialization
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/reflect/annotation/AnnotatedTypeFactory.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,315 @@
+/*
+ * 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 sun.reflect.annotation;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static sun.reflect.annotation.TypeAnnotation.*;
+
+public class AnnotatedTypeFactory {
+    /**
+     * Create an AnnotatedType.
+     *
+     * @param type the type this AnnotatedType corresponds to
+     * @param currentLoc the location this AnnotatedType corresponds to
+     * @param actualTypeAnnos the type annotations this AnnotatedType has
+     * @param allOnSameTarget all type annotation on the same TypeAnnotationTarget
+     *                          as the AnnotatedType being built
+     * @param decl the declaration having the type use this AnnotatedType
+     *                          corresponds to
+     */
+    public static AnnotatedType buildAnnotatedType(Type type,
+                                                   LocationInfo currentLoc,
+                                                   TypeAnnotation[] actualTypeAnnos,
+                                                   TypeAnnotation[] allOnSameTarget,
+                                                   AnnotatedElement decl) {
+        if (type == null) {
+            return EMPTY_ANNOTATED_TYPE;
+        }
+        if (isArray(type))
+            return new AnnotatedArrayTypeImpl(type,
+                    currentLoc,
+                    actualTypeAnnos,
+                    allOnSameTarget,
+                    decl);
+        if (type instanceof Class) {
+            return new AnnotatedTypeBaseImpl(type,
+                    addNesting(type, currentLoc),
+                    actualTypeAnnos,
+                    allOnSameTarget,
+                    decl);
+        } else if (type instanceof TypeVariable) {
+            return new AnnotatedTypeVariableImpl((TypeVariable)type,
+                    currentLoc,
+                    actualTypeAnnos,
+                    allOnSameTarget,
+                    decl);
+        } else if (type instanceof ParameterizedType) {
+            return new AnnotatedParameterizedTypeImpl((ParameterizedType)type,
+                    addNesting(type, currentLoc),
+                    actualTypeAnnos,
+                    allOnSameTarget,
+                    decl);
+        } else if (type instanceof WildcardType) {
+            return new AnnotatedWildcardTypeImpl((WildcardType) type,
+                    currentLoc,
+                    actualTypeAnnos,
+                    allOnSameTarget,
+                    decl);
+        }
+        throw new AssertionError("Unknown instance of Type: " + type + "\nThis should not happen.");
+    }
+
+    private static LocationInfo addNesting(Type type, LocationInfo addTo) {
+        if (isArray(type))
+            return addTo;
+        if (type instanceof Class) {
+            Class<?> clz = (Class)type;
+            if (clz.getEnclosingClass() == null)
+                return addTo;
+            return addNesting(clz.getEnclosingClass(), addTo.pushInner());
+        } else if (type instanceof ParameterizedType) {
+            ParameterizedType t = (ParameterizedType)type;
+            if (t.getOwnerType() == null)
+                return addTo;
+            return addNesting(t.getOwnerType(), addTo.pushInner());
+        }
+        return addTo;
+    }
+
+    private static boolean isArray(Type t) {
+        if (t instanceof Class) {
+            Class<?> c = (Class)t;
+            if (c.isArray())
+                return true;
+        } else if (t instanceof GenericArrayType) {
+            return true;
+        }
+        return false;
+    }
+
+    static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION,
+                                                            new TypeAnnotation[0], new TypeAnnotation[0], null);
+
+    private static class AnnotatedTypeBaseImpl implements AnnotatedType {
+        private final Type type;
+        private final AnnotatedElement decl;
+        private final LocationInfo location;
+        private final TypeAnnotation[] allOnSameTargetTypeAnnotations;
+        private final Map<Class <? extends Annotation>, Annotation> annotations;
+
+        AnnotatedTypeBaseImpl(Type type, LocationInfo location,
+                TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
+                AnnotatedElement decl) {
+            this.type = type;
+            this.decl = decl;
+            this.location = location;
+            this.allOnSameTargetTypeAnnotations = allOnSameTargetTypeAnnotations;
+            this.annotations = TypeAnnotationParser.mapTypeAnnotations(location.filter(actualTypeAnnotations));
+        }
+
+        // AnnotatedElement
+        @Override
+        public final Annotation[] getAnnotations() {
+            return getDeclaredAnnotations();
+        }
+
+        @Override
+        public final <T extends Annotation> T getAnnotation(Class<T> annotation) {
+            return getDeclaredAnnotation(annotation);
+        }
+
+        @Override
+        public final <T extends Annotation> T[] getAnnotations(Class<T> annotation) {
+            return getDeclaredAnnotations(annotation);
+        }
+
+        @Override
+        public Annotation[] getDeclaredAnnotations() {
+            return annotations.values().toArray(new Annotation[0]);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotation) {
+            return (T)annotations.get(annotation);
+        }
+
+        @Override
+        public <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotation) {
+            return AnnotationSupport.getMultipleAnnotations(annotations, annotation);
+        }
+
+        // AnnotatedType
+        @Override
+        public Type getType() {
+            return type;
+        }
+
+        // Implementation details
+        LocationInfo getLocation() {
+            return location;
+        }
+        TypeAnnotation[] getTypeAnnotations() {
+            return allOnSameTargetTypeAnnotations;
+        }
+        AnnotatedElement getDecl() {
+            return decl;
+        }
+    }
+
+    private static class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType {
+        AnnotatedArrayTypeImpl(Type type, LocationInfo location,
+                TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
+                AnnotatedElement decl) {
+            super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
+        }
+
+        @Override
+        public AnnotatedType getAnnotatedGenericComponentType() {
+            return AnnotatedTypeFactory.buildAnnotatedType(getComponentType(),
+                                                           getLocation().pushArray(),
+                                                           getTypeAnnotations(),
+                                                           getTypeAnnotations(),
+                                                           getDecl());
+        }
+
+        private Type getComponentType() {
+            Type t = getType();
+            if (t instanceof Class) {
+                Class<?> c = (Class)t;
+                return c.getComponentType();
+            }
+            return ((GenericArrayType)t).getGenericComponentType();
+        }
+    }
+
+    private static class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable {
+        AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location,
+                TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
+                AnnotatedElement decl) {
+            super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedBounds() {
+            return getTypeVariable().getAnnotatedBounds();
+        }
+
+        private TypeVariable<?> getTypeVariable() {
+            return (TypeVariable)getType();
+        }
+    }
+
+    private static class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedParameterizedType {
+        AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
+                TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
+                AnnotatedElement decl) {
+            super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedActualTypeArguments() {
+            Type[] arguments = getParameterizedType().getActualTypeArguments();
+            AnnotatedType[] res = new AnnotatedType[arguments.length];
+            Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
+            int initialCapacity = getTypeAnnotations().length;
+            for (int i = 0; i < res.length; i++) {
+                List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
+                LocationInfo newLoc = getLocation().pushTypeArg((byte)i);
+                for (TypeAnnotation t : getTypeAnnotations())
+                    if (t.getLocationInfo().isSameLocationInfo(newLoc))
+                        l.add(t);
+                res[i] = buildAnnotatedType(arguments[i],
+                                            newLoc,
+                                            l.toArray(new TypeAnnotation[0]),
+                                            getTypeAnnotations(),
+                                            getDecl());
+            }
+            return res;
+        }
+
+        private ParameterizedType getParameterizedType() {
+            return (ParameterizedType)getType();
+        }
+    }
+
+    private static class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType {
+        private final boolean hasUpperBounds;
+        AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
+                TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
+                AnnotatedElement decl) {
+            super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
+            hasUpperBounds = (type.getLowerBounds().length == 0);
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedUpperBounds() {
+            if (!hasUpperBounds())
+                return new AnnotatedType[0];
+            return getAnnotatedBounds(getWildcardType().getUpperBounds());
+        }
+
+        @Override
+        public AnnotatedType[] getAnnotatedLowerBounds() {
+            if (hasUpperBounds)
+                return new AnnotatedType[0];
+            return getAnnotatedBounds(getWildcardType().getLowerBounds());
+        }
+
+        private AnnotatedType[] getAnnotatedBounds(Type[] bounds) {
+            AnnotatedType[] res = new AnnotatedType[bounds.length];
+            Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
+            LocationInfo newLoc = getLocation().pushWildcard();
+            int initialCapacity = getTypeAnnotations().length;
+            for (int i = 0; i < res.length; i++) {
+                List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
+                for (TypeAnnotation t : getTypeAnnotations())
+                    if (t.getLocationInfo().isSameLocationInfo(newLoc))
+                        l.add(t);
+                res[i] = buildAnnotatedType(bounds[i],
+                                            newLoc,
+                                            l.toArray(new TypeAnnotation[0]),
+                                            getTypeAnnotations(),
+                                            getDecl());
+            }
+            return res;
+        }
+
+        private WildcardType getWildcardType() {
+            return (WildcardType)getType();
+        }
+
+        private boolean hasUpperBounds() {
+            return hasUpperBounds;
+        }
+    }
+}
--- a/src/share/classes/sun/reflect/annotation/AnnotationParser.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/reflect/annotation/AnnotationParser.java	Tue Feb 05 11:11:53 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
@@ -188,7 +188,7 @@
      * available at runtime
      */
     @SuppressWarnings("unchecked")
-    private static Annotation parseAnnotation(ByteBuffer buf,
+    static Annotation parseAnnotation(ByteBuffer buf,
                                               ConstantPool constPool,
                                               Class<?> container,
                                               boolean exceptionOnMissingAnnotationClass) {
--- a/src/share/classes/sun/reflect/annotation/AnnotationSupport.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/reflect/annotation/AnnotationSupport.java	Tue Feb 05 11:11:53 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,63 +27,29 @@
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
-import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import sun.reflect.Reflection;
-import sun.misc.JavaLangAccess;
 
 public final class AnnotationSupport {
-    private static final JavaLangAccess javaLangAccess = sun.misc.SharedSecrets.getJavaLangAccess();
-
-    /**
-     * Finds and returns _one_ annotation of the type indicated by
-     * {@code annotationClass} from the {@code Map} {@code
-     * annotationMap}. Looks into containers of the {@code
-     * annotationClass} (as specified by an the {@code
-     * annotationClass} type being meta-annotated with an {@code
-     * ContainedBy} annotation).
-     *
-     * @param annotationMap the {@code Map} used to store annotations and indexed by their type
-     * @param annotationClass the type of annotation to search for
-     *
-     * @return in instance of {@code annotationClass} or {@code null} if none were found
-     */
-    public static <A extends Annotation> A getOneAnnotation(final Map<Class<? extends Annotation>, Annotation> annotationMap,
-                                                            final Class<A> annotationClass) {
-        @SuppressWarnings("unchecked")
-        final A candidate = (A)annotationMap.get(annotationClass);
-        if (candidate != null) {
-            return candidate;
-        }
-
-        final Class<? extends Annotation> containerClass = getContainer(annotationClass);
-        if (containerClass != null) {
-            return unpackOne(annotationMap.get(containerClass), annotationClass);
-        }
-
-        return null; // found none
-    }
-
     /**
      * Finds and returns all annotation of the type indicated by
      * {@code annotationClass} from the {@code Map} {@code
      * annotationMap}. Looks into containers of the {@code
      * annotationClass} (as specified by an the {@code
      * annotationClass} type being meta-annotated with an {@code
-     * ContainedBy} annotation).
+     * Repeatable} annotation).
      *
      * @param annotationMap the {@code Map} used to store annotations indexed by their type
      * @param annotationClass the type of annotation to search for
      *
      * @return an array of instances of {@code annotationClass} or an empty array if none were found
      */
-    public static  <A extends Annotation> A[] getMultipleAnnotations(final Map<Class<? extends Annotation>, Annotation> annotationMap,
-                                                                     final Class<A> annotationClass) {
-        final ArrayList<A> res = new ArrayList<A>();
+    public static  <A extends Annotation> A[] getMultipleAnnotations(
+            final Map<Class<? extends Annotation>, Annotation> annotationMap,
+            final Class<A> annotationClass) {
+        final List<A> res = new ArrayList<A>();
 
         @SuppressWarnings("unchecked")
         final A candidate = (A)annotationMap.get(annotationClass);
@@ -101,49 +67,10 @@
         return res.isEmpty() ? emptyTemplateArray : res.toArray(emptyTemplateArray);
     }
 
-    /**
-     * Unpacks the {@code annotationMap} parameter into an array of
-     * {@code Annotation}s. This method will unpack all repeating
-     * annotations containers (once). An annotation type is marked as a
-     * container by meta-annotating it the with the {@code
-     * ContainerFor} annotation.
-     *
-     * @param annotationMap the {@code Map} from where the annotations are unpacked
-     *
-     * @return an array of Annotation
-     */
-    public static Annotation[] unpackToArray(Map<Class<? extends Annotation>, Annotation> annotationMap) {
-        List<Annotation> res = new ArrayList<>();
-        for (Map.Entry<Class<? extends Annotation>, Annotation> e : annotationMap.entrySet()) {
-            Class<? extends Annotation> annotationClass = e.getKey();
-            Annotation annotationInstance = e.getValue();
-            Class<? extends Annotation> containee = getContainee(e.getKey());
-            boolean isContainer = javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainerFor.class) != null;
-
-            if (isContainer) {
-                res.addAll(unpackAll(annotationInstance, containee));
-            } else {
-                res.add(annotationInstance);
-            }
-        }
-
-        return res.isEmpty()
-               ? AnnotationParser.getEmptyAnnotationArray()
-               : res.toArray(AnnotationParser.getEmptyAnnotationArray());
-    }
-
     /** Helper to get the container, or null if none, of an annotation. */
     private static <A extends Annotation> Class<? extends Annotation> getContainer(Class<A> annotationClass) {
-        ContainedBy containerAnnotation =
-            javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainedBy.class);
-        return (containerAnnotation == null) ? null : containerAnnotation.value();
-    }
-
-    /** Helper to get the containee, or null if this isn't a container, of a possible container annotation. */
-    private static <A extends Annotation> Class<? extends Annotation> getContainee(Class<A> annotationClass) {
-        ContainerFor containerAnnotation =
-            javaLangAccess.getDirectDeclaredAnnotation(annotationClass, ContainerFor.class);
-        return (containerAnnotation == null) ? null : containerAnnotation.value();
+        Repeatable containingAnnotation = annotationClass.getDeclaredAnnotation(Repeatable.class);
+        return (containingAnnotation == null) ? null : containingAnnotation.value();
     }
 
     /** Reflectively look up and get the returned array from the the
@@ -156,14 +83,15 @@
             // value element. Get the AnnotationType, get the "value" element
             // and invoke it to get the contents.
 
-            Class<?> containerClass = containerInstance.annotationType();
-            AnnotationType annoType = javaLangAccess.getAnnotationType(containerClass);
+            Class<? extends Annotation> containerClass = containerInstance.annotationType();
+            AnnotationType annoType = AnnotationType.getInstance(containerClass);
             if (annoType == null)
                 throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations");
 
             Method m = annoType.members().get("value");
             if (m == null)
-                throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations");
+                throw new InvalidContainerAnnotationError(containerInstance +
+                                                          " is an invalid container for repeating annotations");
             m.setAccessible(true);
 
             @SuppressWarnings("unchecked") // not provably safe, but we catch the ClassCastException
@@ -175,32 +103,11 @@
                  IllegalArgumentException | // parameters doesn't match
                  InvocationTargetException | // the value method threw an exception
                  ClassCastException e) { // well, a cast failed ...
-            throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations",
-                                                      e,
-                                                      containerInstance,
-                                                      null);
-        }
-    }
-
-    /* Sanity check type of and return the first annotation instance
-     * of type {@code annotationClass} from {@code
-     * containerInstance}.
-     */
-    private static <A extends Annotation> A unpackOne(Annotation containerInstance, Class<A> annotationClass) {
-        if (containerInstance == null) {
-            return null;
-        }
-
-        try {
-            return annotationClass.cast(getValueArray(containerInstance)[0]);
-        } catch (ArrayIndexOutOfBoundsException | // empty array
-                 ClassCastException | // well, a cast failed ...
-                 NullPointerException e) { // can this NP? for good meassure
-            throw new InvalidContainerAnnotationError(String.format("%s is an invalid container for repeating annotations of type: %s",
-                                                                    containerInstance, annotationClass),
-                                                      e,
-                                                      containerInstance,
-                                                      annotationClass);
+            throw new InvalidContainerAnnotationError(
+                    containerInstance + " is an invalid container for repeating annotations",
+                    e,
+                    containerInstance,
+                    null);
         }
     }
 
@@ -208,24 +115,26 @@
      * instances of type {@code annotationClass} from {@code
      * containerInstance}.
      */
-    private static <A extends Annotation> List<A> unpackAll(Annotation containerInstance, Class<A> annotationClass) {
+    private static <A extends Annotation> List<A> unpackAll(Annotation containerInstance,
+                                                            Class<A> annotationClass) {
         if (containerInstance == null) {
             return Collections.emptyList(); // container not present
         }
 
         try {
             A[] a = getValueArray(containerInstance);
-            ArrayList<A> l = new ArrayList<>(a.length);
+            List<A> l = new ArrayList<>(a.length);
             for (int i  = 0; i < a.length; i++)
                 l.add(annotationClass.cast(a[i]));
             return l;
         } catch (ClassCastException |
                  NullPointerException e) {
-            throw new InvalidContainerAnnotationError(String.format("%s is an invalid container for repeating annotations of type: %s",
-                                                                    containerInstance, annotationClass),
-                                                      e,
-                                                      containerInstance,
-                                                      annotationClass);
+            throw new InvalidContainerAnnotationError(
+                    String.format("%s is an invalid container for repeating annotations of type: %s",
+                        containerInstance, annotationClass),
+                    e,
+                    containerInstance,
+                    annotationClass);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/reflect/annotation/TypeAnnotation.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,227 @@
+/*
+ * 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 sun.reflect.annotation;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationFormatError;
+import java.lang.reflect.AnnotatedElement;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A TypeAnnotation contains all the information needed to transform type
+ * annotations on declarations in the class file to actual Annotations in
+ * AnnotatedType instances.
+ *
+ * TypeAnnotaions contain a base Annotation, location info (which lets you
+ * distinguish between '@A Inner.@B Outer' in for example nested types),
+ * target info and the declaration the TypeAnnotaiton was parsed from.
+ */
+public class TypeAnnotation {
+    private final TypeAnnotationTargetInfo targetInfo;
+    private final LocationInfo loc;
+    private final Annotation annotation;
+    private final AnnotatedElement baseDeclaration;
+
+    public TypeAnnotation(TypeAnnotationTargetInfo targetInfo,
+                          LocationInfo loc,
+                          Annotation annotation,
+                          AnnotatedElement baseDeclaration) {
+        this.targetInfo = targetInfo;
+        this.loc = loc;
+        this.annotation = annotation;
+        this.baseDeclaration = baseDeclaration;
+    }
+
+    public TypeAnnotationTargetInfo getTargetInfo() {
+        return targetInfo;
+    }
+    public Annotation getAnnotation() {
+        return annotation;
+    }
+    public AnnotatedElement getBaseDeclaration() {
+        return baseDeclaration;
+    }
+    public LocationInfo getLocationInfo() {
+        return loc;
+    }
+
+    public static List<TypeAnnotation> filter(TypeAnnotation[] typeAnnotations,
+                                              TypeAnnotationTarget predicate) {
+        ArrayList<TypeAnnotation> typeAnnos = new ArrayList<>(typeAnnotations.length);
+        for (TypeAnnotation t : typeAnnotations)
+            if (t.getTargetInfo().getTarget() == predicate)
+                typeAnnos.add(t);
+        typeAnnos.trimToSize();
+        return typeAnnos;
+    }
+
+    public static enum TypeAnnotationTarget {
+        CLASS_TYPE_PARAMETER,
+        METHOD_TYPE_PARAMETER,
+        CLASS_EXTENDS,
+        CLASS_IMPLEMENTS,
+        CLASS_PARAMETER_BOUND,
+        METHOD_PARAMETER_BOUND,
+        METHOD_RETURN_TYPE,
+        METHOD_RECEIVER_TYPE,
+        FIELD_TYPE,
+        THROWS;
+    }
+    public static class TypeAnnotationTargetInfo {
+        private final TypeAnnotationTarget target;
+        private final int count;
+        private final int secondaryIndex;
+        private static final int UNUSED_INDEX = -2; // this is not a valid index in the 308 spec
+
+        public TypeAnnotationTargetInfo(TypeAnnotationTarget target) {
+            this(target, UNUSED_INDEX, UNUSED_INDEX);
+        }
+
+        public TypeAnnotationTargetInfo(TypeAnnotationTarget target,
+                                        int count) {
+            this(target, count, UNUSED_INDEX);
+        }
+
+        public TypeAnnotationTargetInfo(TypeAnnotationTarget target,
+                                        int count,
+                                        int secondaryIndex) {
+            this.target = target;
+            this.count = count;
+            this.secondaryIndex = secondaryIndex;
+        }
+
+        public TypeAnnotationTarget getTarget() {
+            return target;
+        }
+        public int getCount() {
+            return count;
+        }
+        public int getSecondaryIndex() {
+            return secondaryIndex;
+        }
+
+        @Override
+        public String toString() {
+            return "" + target + ": " + count + ", " + secondaryIndex;
+        }
+    }
+
+    public static class LocationInfo {
+        private final int depth;
+        private final Location[] locations;
+
+        private LocationInfo() {
+            this(0, new Location[0]);
+        }
+        private LocationInfo(int depth, Location[] locations) {
+            this.depth = depth;
+            this.locations = locations;
+        }
+
+        public static final LocationInfo BASE_LOCATION = new LocationInfo();
+
+        public static LocationInfo parseLocationInfo(ByteBuffer buf) {
+            int depth = buf.get();
+            if (depth == 0)
+                return BASE_LOCATION;
+            Location[] locations = new Location[depth];
+            for (int i = 0; i < depth; i++) {
+                byte tag = buf.get();
+                byte index = buf.get();
+                if (!(tag == 0 || tag == 1 | tag == 2 || tag == 3))
+                    throw new AnnotationFormatError("Bad Location encoding in Type Annotation");
+                if (tag != 3 && index != 0)
+                    throw new AnnotationFormatError("Bad Location encoding in Type Annotation");
+                locations[i] = new Location(tag, index);
+            }
+            return new LocationInfo(depth, locations);
+        }
+
+        public LocationInfo pushArray() {
+            return pushLocation((byte)0, (byte)0);
+        }
+
+        public LocationInfo pushInner() {
+            return pushLocation((byte)1, (byte)0);
+        }
+
+        public LocationInfo pushWildcard() {
+            return pushLocation((byte) 2, (byte) 0);
+        }
+
+        public LocationInfo pushTypeArg(byte index) {
+            return pushLocation((byte) 3, index);
+        }
+
+        public LocationInfo pushLocation(byte tag, byte index) {
+            int newDepth = this.depth + 1;
+            Location[] res = new Location[newDepth];
+            System.arraycopy(this.locations, 0, res, 0, depth);
+            res[newDepth - 1] = new Location(tag, index);
+            return new LocationInfo(newDepth, res);
+        }
+
+        public TypeAnnotation[] filter(TypeAnnotation[] ta) {
+            ArrayList<TypeAnnotation> l = new ArrayList<>(ta.length);
+            for (TypeAnnotation t : ta) {
+                if (isSameLocationInfo(t.getLocationInfo()))
+                    l.add(t);
+            }
+            return l.toArray(new TypeAnnotation[0]);
+        }
+
+        boolean isSameLocationInfo(LocationInfo other) {
+            if (depth != other.depth)
+                return false;
+            for (int i = 0; i < depth; i++)
+                if (!locations[i].isSameLocation(other.locations[i]))
+                    return false;
+            return true;
+        }
+
+        public static class Location {
+            public final byte tag;
+            public final byte index;
+
+            boolean isSameLocation(Location other) {
+                return tag == other.tag && index == other.index;
+            }
+
+            public Location(byte tag, byte index) {
+                this.tag = tag;
+                this.index = index;
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return annotation.toString() + " with Targetnfo: " +
+            targetInfo.toString() + " on base declaration: " +
+            baseDeclaration.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/reflect/annotation/TypeAnnotationParser.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,491 @@
+/*
+ * 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 sun.reflect.annotation;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.nio.ByteBuffer;
+import java.nio.BufferUnderflowException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import sun.misc.JavaLangAccess;
+import sun.reflect.ConstantPool;
+import static sun.reflect.annotation.TypeAnnotation.*;
+
+/**
+ * TypeAnnotationParser implements the logic needed to parse
+ * TypeAnnotations from an array of bytes.
+ */
+public class TypeAnnotationParser {
+    private static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0];
+
+    /**
+     * Build an AnnotatedType from the parameters supplied.
+     *
+     * This method and {@code buildAnnotatedTypes} are probably
+     * the entry points you are looking for.
+     *
+     * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
+     * @param cp the ConstantPool needed to parse the embedded Annotation
+     * @param decl the dclaration this type annotation is on
+     * @param container the Class this type annotation is on (may be the same as decl)
+     * @param type the type the AnnotatedType corresponds to
+     * @param filter the type annotation targets included in this AnnotatedType
+     */
+    public static AnnotatedType buildAnnotatedType(byte[] rawAnnotations,
+            ConstantPool cp,
+            AnnotatedElement decl,
+            Class<?> container,
+            Type type,
+            TypeAnnotationTarget filter) {
+        TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
+                                                    cp,
+                                                    decl,
+                                                    container);
+        List<TypeAnnotation> l = new ArrayList<>(tas.length);
+        for (TypeAnnotation t : tas) {
+            TypeAnnotationTargetInfo ti = t.getTargetInfo();
+            if (ti.getTarget() == filter)
+                l.add(t);
+        }
+        TypeAnnotation[] typeAnnotations = l.toArray(new TypeAnnotation[0]);
+        return AnnotatedTypeFactory.buildAnnotatedType(type,
+                                                       LocationInfo.BASE_LOCATION,
+                                                       typeAnnotations,
+                                                       typeAnnotations,
+                                                       decl);
+    }
+
+    /**
+     * Build an array of AnnotatedTypes from the parameters supplied.
+     *
+     * This method and {@code buildAnnotatedType} are probably
+     * the entry points you are looking for.
+     *
+     * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
+     * @param cp the ConstantPool needed to parse the embedded Annotation
+     * @param decl the declaration this type annotation is on
+     * @param container the Class this type annotation is on (may be the same as decl)
+     * @param types the Types the AnnotatedTypes corresponds to
+     * @param filter the type annotation targets that included in this AnnotatedType
+     */
+    public static AnnotatedType[] buildAnnotatedTypes(byte[] rawAnnotations,
+            ConstantPool cp,
+            AnnotatedElement decl,
+            Class<?> container,
+            Type[] types,
+            TypeAnnotationTarget filter) {
+        int size = types.length;
+        AnnotatedType[] result = new AnnotatedType[size];
+        Arrays.fill(result, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE);
+        @SuppressWarnings("rawtypes")
+        ArrayList[] l = new ArrayList[size]; // array of ArrayList<TypeAnnotation>
+
+        TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
+                                                    cp,
+                                                    decl,
+                                                    container);
+        for (TypeAnnotation t : tas) {
+            TypeAnnotationTargetInfo ti = t.getTargetInfo();
+            if (ti.getTarget() == filter) {
+                int pos = ti.getCount();
+                if (l[pos] == null) {
+                    ArrayList<TypeAnnotation> tmp = new ArrayList<>(tas.length);
+                    l[pos] = tmp;
+                }
+                @SuppressWarnings("unchecked")
+                ArrayList<TypeAnnotation> tmp = l[pos];
+                tmp.add(t);
+            }
+        }
+        for (int i = 0; i < size; i++) {
+            @SuppressWarnings("unchecked")
+            ArrayList<TypeAnnotation> list = l[i];
+            if (list != null) {
+                TypeAnnotation[] typeAnnotations = list.toArray(new TypeAnnotation[0]);
+                result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
+                                                                    LocationInfo.BASE_LOCATION,
+                                                                    typeAnnotations,
+                                                                    typeAnnotations,
+                                                                    decl);
+            }
+        }
+        return result;
+    }
+
+    // Class helpers
+
+    /**
+     * Build an AnnotatedType for the class decl's supertype.
+     *
+     * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
+     * @param cp the ConstantPool needed to parse the embedded Annotation
+     * @param decl the Class which annotated supertype is being built
+     */
+    public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations,
+            ConstantPool cp,
+            Class<?> decl) {
+        Type supertype = decl.getGenericSuperclass();
+        if (supertype == null)
+            return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE;
+        return buildAnnotatedType(rawAnnotations,
+                                  cp,
+                                  decl,
+                                  decl,
+                                  supertype,
+                                  TypeAnnotationTarget.CLASS_EXTENDS);
+    }
+
+    /**
+     * Build an array of AnnotatedTypes for the class decl's implemented
+     * interfaces.
+     *
+     * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
+     * @param cp the ConstantPool needed to parse the embedded Annotation
+     * @param decl the Class whose annotated implemented interfaces is being built
+     */
+    public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations,
+            ConstantPool cp,
+            Class<?> decl) {
+        return buildAnnotatedTypes(rawAnnotations,
+                                   cp,
+                                   decl,
+                                   decl,
+                                   decl.getGenericInterfaces(),
+                                   TypeAnnotationTarget.CLASS_IMPLEMENTS);
+    }
+
+    // TypeVariable helpers
+
+    /**
+     * Parse regular annotations on a TypeVariable declared on genericDecl.
+     *
+     * Regular Annotations on TypeVariables are stored in the type
+     * annotation byte[] in the class file.
+     *
+     * @param genericsDecl the declaration declaring the type variable
+     * @param typeVarIndex the 0-based index of this type variable in the declaration
+     */
+    public static <D extends GenericDeclaration> Annotation[] parseTypeVariableAnnotations(D genericDecl,
+            int typeVarIndex) {
+        AnnotatedElement decl;
+        TypeAnnotationTarget predicate;
+        if (genericDecl instanceof Class) {
+            decl = (Class<?>)genericDecl;
+            predicate = TypeAnnotationTarget.CLASS_TYPE_PARAMETER;
+        } else if (genericDecl instanceof Executable) {
+            decl = (Executable)genericDecl;
+            predicate = TypeAnnotationTarget.METHOD_TYPE_PARAMETER;
+        } else {
+            throw new AssertionError("Unknown GenericDeclaration " + genericDecl + "\nthis should not happen.");
+        }
+        List<TypeAnnotation> typeVarAnnos = TypeAnnotation.filter(parseAllTypeAnnotations(decl),
+                                                                  predicate);
+        List<Annotation> res = new ArrayList<>(typeVarAnnos.size());
+        for (TypeAnnotation t : typeVarAnnos)
+            if (t.getTargetInfo().getCount() == typeVarIndex)
+                res.add(t.getAnnotation());
+        return res.toArray(new Annotation[0]);
+    }
+
+    /**
+     * Build an array of AnnotatedTypes for the declaration decl's bounds.
+     *
+     * @param bounds the bounds corresponding to the annotated bounds
+     * @param decl the declaration whose annotated bounds is being built
+     * @param typeVarIndex the index of this type variable on the decl
+     */
+    public static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds,
+            D decl,
+            int typeVarIndex) {
+        return parseAnnotatedBounds(bounds, decl, typeVarIndex, LocationInfo.BASE_LOCATION);
+    }
+    //helper for above
+    static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds,
+            D decl,
+            int typeVarIndex,
+            LocationInfo loc) {
+        List<TypeAnnotation> candidates = fetchBounds(decl);
+        if (bounds != null) {
+            int startIndex = 0;
+            AnnotatedType[] res = new AnnotatedType[bounds.length];
+            Arrays.fill(res, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE);
+
+            // Adjust bounds index
+            //
+            // Figure out if the type annotations for this bound starts with 0
+            // or 1. The spec says within a bound the 0:th type annotation will
+            // always be on an bound of a Class type (not Interface type). So
+            // if the programmer starts with an Interface type for the first
+            // (and following) bound(s) the implicit Object bound is considered
+            // the first (that is 0:th) bound and type annotations start on
+            // index 1.
+            if (bounds.length > 0) {
+                Type b0 = bounds[0];
+                if (!(b0 instanceof Class<?>)) {
+                    startIndex = 1;
+                } else {
+                    Class<?> c = (Class<?>)b0;
+                    if (c.isInterface()) {
+                        startIndex = 1;
+                    }
+                }
+            }
+
+            for (int i = 0; i < bounds.length; i++) {
+                List<TypeAnnotation> l = new ArrayList<>(candidates.size());
+                for (TypeAnnotation t : candidates) {
+                    TypeAnnotationTargetInfo tInfo = t.getTargetInfo();
+                    if (tInfo.getSecondaryIndex() == i + startIndex &&
+                            tInfo.getCount() == typeVarIndex) {
+                        l.add(t);
+                    }
+                    res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
+                                                                     loc,
+                                                                     l.toArray(new TypeAnnotation[0]),
+                                                                     candidates.toArray(new TypeAnnotation[0]),
+                                                                     (AnnotatedElement)decl);
+                }
+            }
+            return res;
+        }
+        return new AnnotatedType[0];
+    }
+    private static <D extends GenericDeclaration> List<TypeAnnotation> fetchBounds(D decl) {
+        AnnotatedElement boundsDecl;
+        TypeAnnotationTarget target;
+        if (decl instanceof Class) {
+            target = TypeAnnotationTarget.CLASS_PARAMETER_BOUND;
+            boundsDecl = (Class)decl;
+        } else {
+            target = TypeAnnotationTarget.METHOD_PARAMETER_BOUND;
+            boundsDecl = (Executable)decl;
+        }
+        return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target);
+    }
+
+    /*
+     * Parse all type annotations on the declaration supplied. This is needed
+     * when you go from for example an annotated return type on a method that
+     * is a type variable declared on the class. In this case you need to
+     * 'jump' to the decl of the class and parse all type annotations there to
+     * find the ones that are applicable to the type variable.
+     */
+    static TypeAnnotation[] parseAllTypeAnnotations(AnnotatedElement decl) {
+        Class<?> container;
+        byte[] rawBytes;
+        JavaLangAccess javaLangAccess = sun.misc.SharedSecrets.getJavaLangAccess();
+        if (decl instanceof Class) {
+            container = (Class<?>)decl;
+            rawBytes = javaLangAccess.getRawClassTypeAnnotations(container);
+        } else if (decl instanceof Executable) {
+            container = ((Executable)decl).getDeclaringClass();
+            rawBytes = javaLangAccess.getRawExecutableTypeAnnotations((Executable)decl);
+        } else {
+            // Should not reach here. Assert?
+            return EMPTY_TYPE_ANNOTATION_ARRAY;
+        }
+        return parseTypeAnnotations(rawBytes, javaLangAccess.getConstantPool(container),
+                                    decl, container);
+    }
+
+    /* Parse type annotations encoded as an array of bytes */
+    private static TypeAnnotation[] parseTypeAnnotations(byte[] rawAnnotations,
+            ConstantPool cp,
+            AnnotatedElement baseDecl,
+            Class<?> container) {
+        if (rawAnnotations == null)
+            return EMPTY_TYPE_ANNOTATION_ARRAY;
+
+        ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
+        int annotationCount = buf.getShort() & 0xFFFF;
+        List<TypeAnnotation> typeAnnotations = new ArrayList<>(annotationCount);
+
+        // Parse each TypeAnnotation
+        for (int i = 0; i < annotationCount; i++) {
+             TypeAnnotation ta = parseTypeAnnotation(buf, cp, baseDecl, container);
+             if (ta != null)
+                 typeAnnotations.add(ta);
+        }
+
+        return typeAnnotations.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
+    }
+
+
+    // Helper
+    static Map<Class<? extends Annotation>, Annotation> mapTypeAnnotations(TypeAnnotation[] typeAnnos) {
+        Map<Class<? extends Annotation>, Annotation> result =
+            new LinkedHashMap<>();
+        for (TypeAnnotation t : typeAnnos) {
+            Annotation a = t.getAnnotation();
+            Class<? extends Annotation> klass = a.annotationType();
+            AnnotationType type = AnnotationType.getInstance(klass);
+            if (type.retention() == RetentionPolicy.RUNTIME)
+                if (result.put(klass, a) != null)
+                    throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
+        }
+        return result;
+    }
+
+    // Position codes
+    // Regular type parameter annotations
+    private static final byte CLASS_TYPE_PARAMETER = 0x00;
+    private static final byte METHOD_TYPE_PARAMETER = 0x01;
+    // Type Annotations outside method bodies
+    private static final byte CLASS_EXTENDS = 0x10;
+    private static final byte CLASS_TYPE_PARAMETER_BOUND = 0x11;
+    private static final byte METHOD_TYPE_PARAMETER_BOUND = 0x12;
+    private static final byte FIELD = 0x13;
+    private static final byte METHOD_RETURN = 0x14;
+    private static final byte METHOD_RECEIVER = 0x15;
+    private static final byte METHOD_FORMAL_PARAMETER = 0x16;
+    private static final byte THROWS = 0x17;
+    // Type Annotations inside method bodies
+    private static final byte LOCAL_VARIABLE = (byte)0x40;
+    private static final byte RESOURCE_VARIABLE = (byte)0x41;
+    private static final byte EXCEPTION_PARAMETER = (byte)0x42;
+    private static final byte CAST = (byte)0x43;
+    private static final byte INSTANCEOF = (byte)0x44;
+    private static final byte NEW = (byte)0x45;
+    private static final byte CONSTRUCTOR_REFERENCE_RECEIVER = (byte)0x46;
+    private static final byte METHOD_REFERENCE_RECEIVER = (byte)0x47;
+    private static final byte LAMBDA_FORMAL_PARAMETER = (byte)0x48;
+    private static final byte METHOD_REFERENCE = (byte)0x49;
+    private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x50;
+
+    private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf,
+            ConstantPool cp,
+            AnnotatedElement baseDecl,
+            Class<?> container) {
+        TypeAnnotationTargetInfo ti = parseTargetInfo(buf);
+        LocationInfo locationInfo = LocationInfo.parseLocationInfo(buf);
+        Annotation a = AnnotationParser.parseAnnotation(buf, cp, container, false);
+        if (ti == null) // Inside a method for example
+            return null;
+        return new TypeAnnotation(ti, locationInfo, a, baseDecl);
+    }
+
+    private static TypeAnnotationTargetInfo parseTargetInfo(ByteBuffer buf) {
+        byte posCode = buf.get();
+        switch(posCode) {
+        case CLASS_TYPE_PARAMETER:
+        case METHOD_TYPE_PARAMETER: {
+            byte index = buf.get();
+            TypeAnnotationTargetInfo res;
+            if (posCode == CLASS_TYPE_PARAMETER)
+                res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_TYPE_PARAMETER,
+                        index);
+            else
+                res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_TYPE_PARAMETER,
+                        index);
+            return res;
+            } // unreachable break;
+        case CLASS_EXTENDS: {
+            short index = buf.getShort();
+            if (index == -1) {
+                return new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_EXTENDS);
+            } else if (index >= 0) {
+                TypeAnnotationTargetInfo res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_IMPLEMENTS,
+                        index);
+                return res;
+            }} break;
+        case CLASS_TYPE_PARAMETER_BOUND:
+            return parse2ByteTarget(TypeAnnotationTarget.CLASS_PARAMETER_BOUND, buf);
+        case METHOD_TYPE_PARAMETER_BOUND:
+            return parse2ByteTarget(TypeAnnotationTarget.METHOD_PARAMETER_BOUND, buf);
+        case FIELD:
+            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD_TYPE);
+        case METHOD_RETURN:
+            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN_TYPE);
+        case METHOD_RECEIVER:
+            return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER_TYPE);
+        case METHOD_FORMAL_PARAMETER: {
+            // Todo
+            byte index = buf.get();
+            } break;
+        case THROWS:
+            return parseShortTarget(TypeAnnotationTarget.THROWS, buf);
+
+        /*
+         * The ones below are inside method bodies, we don't care about them for core reflection
+         * other than adjusting for them in the byte stream.
+         */
+        case LOCAL_VARIABLE:
+        case RESOURCE_VARIABLE:
+            short length = buf.getShort();
+            for (int i = 0; i < length; ++i) {
+                short offset = buf.getShort();
+                short varLength = buf.getShort();
+                short index = buf.getShort();
+            }
+            break;
+        case EXCEPTION_PARAMETER: {
+            byte index = buf.get();
+            } break;
+        case CAST:
+        case INSTANCEOF:
+        case NEW: {
+            short offset = buf.getShort();
+            } break;
+        case CONSTRUCTOR_REFERENCE_RECEIVER:
+        case METHOD_REFERENCE_RECEIVER: {
+            short offset = buf.getShort();
+            byte index = buf.get();
+            } break;
+        case LAMBDA_FORMAL_PARAMETER: {
+            byte index = buf.get();
+            } break;
+        case METHOD_REFERENCE:
+            // This one isn't in the spec yet
+            break;
+        case METHOD_REFERENCE_TYPE_ARGUMENT: {
+            short offset = buf.getShort();
+            byte index = buf.get();
+            } break;
+
+        default:
+            // will throw error below
+            break;
+        }
+        throw new AnnotationFormatError("Could not parse bytes for type annotations");
+    }
+
+    private static TypeAnnotationTargetInfo parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf) {
+        short index = buf.getShort();
+        return new TypeAnnotationTargetInfo(target, index);
+    }
+    private static TypeAnnotationTargetInfo parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf) {
+        byte count = buf.get();
+        byte secondaryIndex = buf.get();
+        return new TypeAnnotationTargetInfo(target,
+                                            count,
+                                            secondaryIndex);
+    }
+}
--- a/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java	Tue Feb 05 11:11:53 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
@@ -25,13 +25,18 @@
 
 package sun.reflect.generics.reflectiveObjects;
 
-import java.lang.annotation.Annotation;
+import java.lang.annotation.*;
+import java.lang.reflect.AnnotatedType;
 import java.lang.reflect.Array;
 import java.lang.reflect.GenericDeclaration;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import java.util.Objects;
-
+import sun.reflect.annotation.AnnotationSupport;
+import sun.reflect.annotation.TypeAnnotationParser;
+import sun.reflect.annotation.AnnotationType;
 import sun.reflect.generics.factory.GenericsFactory;
 import sun.reflect.generics.tree.FieldTypeSignature;
 import sun.reflect.generics.visitor.Reifier;
@@ -182,45 +187,70 @@
         return genericDeclaration.hashCode() ^ name.hashCode();
     }
 
-    // Currently vacuous implementations of AnnotatedElement methods.
-    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
-        Objects.requireNonNull(annotationClass);
-        return false;
-    }
-
+    // Implementations of AnnotatedElement methods.
+    @SuppressWarnings("unchecked")
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-        return null;
+        // T is an Annotation type, the return value of get will be an annotation
+        return (T)mapAnnotations(getAnnotations()).get(annotationClass);
     }
 
     public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-        return null;
+        return getAnnotation(annotationClass);
     }
 
-    @SuppressWarnings("unchecked")
     public <T extends Annotation> T[] getAnnotations(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-        // safe because annotationClass is the class for T
-        return (T[])Array.newInstance(annotationClass, 0);
+        return AnnotationSupport.getMultipleAnnotations(mapAnnotations(getAnnotations()), annotationClass);
     }
 
-    @SuppressWarnings("unchecked")
     public <T extends Annotation> T[] getDeclaredAnnotations(Class<T> annotationClass) {
         Objects.requireNonNull(annotationClass);
-        // safe because annotationClass is the class for T
-        return (T[])Array.newInstance(annotationClass, 0);
+        return getAnnotations(annotationClass);
     }
 
     public Annotation[] getAnnotations() {
-        // Since zero-length, don't need defensive clone
-        return EMPTY_ANNOTATION_ARRAY;
+        int myIndex = typeVarIndex();
+        if (myIndex < 0)
+            throw new AssertionError("Index must be non-negative.");
+        return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex);
     }
 
     public Annotation[] getDeclaredAnnotations() {
-        // Since zero-length, don't need defensive clone
-        return EMPTY_ANNOTATION_ARRAY;
+        return getAnnotations();
+    }
+
+    public AnnotatedType[] getAnnotatedBounds() {
+        return TypeAnnotationParser.parseAnnotatedBounds(getBounds(),
+                                                         getGenericDeclaration(),
+                                                         typeVarIndex());
     }
 
     private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
+
+    // Helpers for annotation methods
+    private int typeVarIndex() {
+        TypeVariable<?>[] tVars = getGenericDeclaration().getTypeParameters();
+        int i = -1;
+        for (TypeVariable<?> v : tVars) {
+            i++;
+            if (equals(v))
+                return i;
+        }
+        return -1;
+    }
+
+    private static Map<Class<? extends Annotation>, Annotation> mapAnnotations(Annotation[] annos) {
+        Map<Class<? extends Annotation>, Annotation> result =
+            new LinkedHashMap<>();
+        for (Annotation a : annos) {
+            Class<? extends Annotation> klass = a.annotationType();
+            AnnotationType type = AnnotationType.getInstance(klass);
+            if (type.retention() == RetentionPolicy.RUNTIME)
+                if (result.put(klass, a) != null)
+                    throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
+        }
+        return result;
+    }
 }
--- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1116,7 +1116,7 @@
         if (privateKeyCount > 0 || secretKeyCount > 0) {
 
             if (debug != null) {
-                debug.println("Storing " + privateKeyCount +
+                debug.println("Storing " + (privateKeyCount + secretKeyCount) +
                     " protected key(s) in a PKCS#7 data content-type");
             }
 
@@ -2122,6 +2122,7 @@
                 SecretKeyEntry kEntry = new SecretKeyEntry();
                 kEntry.protectedSecretKey = secretValue.getOctetString();
                 bagItem = kEntry;
+                secretKeyCount++;
             } else {
 
                 if (debug != null) {
@@ -2220,6 +2221,10 @@
                 if (bagItem instanceof PrivateKeyEntry) {
                     keyList.add((PrivateKeyEntry) entry);
                 }
+                if (entry.attributes == null) {
+                    entry.attributes = new HashSet<>();
+                }
+                entry.attributes.addAll(attributes);
                 if (alias == null) {
                    alias = getUnfriendlyName();
                 }
--- a/src/share/javavm/export/jvm.h	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/javavm/export/jvm.h	Tue Feb 05 11:11:53 2013 -0800
@@ -465,6 +465,12 @@
 JNIEXPORT jbyteArray JNICALL
 JVM_GetClassAnnotations(JNIEnv *env, jclass cls);
 
+/* Type use annotations support (JDK 1.8) */
+
+JNIEXPORT jbyteArray JNICALL
+JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls);
+
+
 /*
  * New (JDK 1.4) reflection implementation
  */
--- a/src/share/native/java/lang/Class.c	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/share/native/java/lang/Class.c	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,7 +75,8 @@
     {"getRawAnnotations",      "()" BA,        (void *)&JVM_GetClassAnnotations},
     {"getConstantPool",     "()" CPL,       (void *)&JVM_GetClassConstantPool},
     {"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},
-    {"getEnclosingMethod0", "()[" OBJ,      (void *)&JVM_GetEnclosingMethodInfo}
+    {"getEnclosingMethod0", "()[" OBJ,      (void *)&JVM_GetEnclosingMethodInfo},
+    {"getRawTypeAnnotations", "()" BA,      (void *)&JVM_GetClassTypeAnnotations},
 };
 
 #undef OBJ
--- a/src/solaris/native/java/net/linux_close.c	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/solaris/native/java/net/linux_close.c	Tue Feb 05 11:11:53 2013 -0800
@@ -192,17 +192,6 @@
 
     {
         /*
-         * Send a wakeup signal to all threads blocked on this
-         * file descriptor.
-         */
-        threadEntry_t *curr = fdEntry->threads;
-        while (curr != NULL) {
-            curr->intr = 1;
-            pthread_kill( curr->thr, sigWakeup );
-            curr = curr->next;
-        }
-
-        /*
          * And close/dup the file descriptor
          * (restart if interrupted by signal)
          */
@@ -214,6 +203,16 @@
             }
         } while (rv == -1 && errno == EINTR);
 
+        /*
+         * Send a wakeup signal to all threads blocked on this
+         * file descriptor.
+         */
+        threadEntry_t *curr = fdEntry->threads;
+        while (curr != NULL) {
+            curr->intr = 1;
+            pthread_kill( curr->thr, sigWakeup );
+            curr = curr->next;
+        }
     }
 
     /*
--- a/src/windows/bin/cmdtoargs.c	Tue Feb 05 11:10:07 2013 -0800
+++ b/src/windows/bin/cmdtoargs.c	Tue Feb 05 11:11:53 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
@@ -104,6 +104,11 @@
 
         case ' ':
         case '\t':
+            if (prev == '\\') {
+                for (i = 0 ; i < slashes; i++) {
+                   *dest++ = prev;
+                }
+            }
             if (quotes % 2 == 1) {
                 *dest++ = ch;
             } else {
@@ -591,6 +596,12 @@
     // v->disable();
     vectors[i++] = v;
 
+    v= new Vector(argv[0], "a b\\\\ d");
+    v->add("a", FALSE);
+    v->add("b\\\\", FALSE);
+    v->add("d", FALSE);
+    vectors[i++] = v;
+
     dotest(vectors);
     printf("All tests pass [%d]\n", i);
     doexit(0);
--- a/test/ProblemList.txt	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/ProblemList.txt	Tue Feb 05 11:11:53 2013 -0800
@@ -321,12 +321,12 @@
 tools/pack200/CommandLineTests.java                             generic-all
 tools/pack200/Pack200Test.java                                  generic-all
 
-# 8001163
-tools/pack200/AttributeTests.java                               generic-all
-
 # 7150569
 tools/launcher/UnicodeTest.java                                 macosx-all
 
+# 8007410
+tools/launcher/FXLauncherTest.java                              linux-all
+
 ############################################################################
 
 # jdk_jdi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/annotation/TypeAnnotationReflection.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,428 @@
+/*
+ * 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 8004698
+ * @summary Unit test for type annotations
+ */
+
+import java.util.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.io.Serializable;
+
+public class TypeAnnotationReflection {
+    public static void main(String[] args) throws Exception {
+        testSuper();
+        testInterfaces();
+        testReturnType();
+        testNested();
+        testArray();
+        testRunException();
+        testClassTypeVarBounds();
+        testMethodTypeVarBounds();
+        testFields();
+        testClassTypeVar();
+        testMethodTypeVar();
+        testParameterizedType();
+        testNestedParameterizedType();
+        testWildcardType();
+    }
+
+    private static void check(boolean b) {
+        if (!b)
+            throw new RuntimeException();
+    }
+
+    private static void testSuper() throws Exception {
+        check(Object.class.getAnnotatedSuperclass().getAnnotations().length == 0);
+        check(Class.class.getAnnotatedSuperclass().getAnnotations().length == 0);
+
+        AnnotatedType a;
+        a = TestClassArray.class.getAnnotatedSuperclass();
+        Annotation[] annos = a.getAnnotations();
+        check(annos.length == 2);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(annos[1].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno)annos[0]).value().equals("extends"));
+        check(((TypeAnno2)annos[1]).value().equals("extends2"));
+    }
+
+    private static void testInterfaces() throws Exception {
+        AnnotatedType[] as;
+        as = TestClassArray.class.getAnnotatedInterfaces();
+        check(as.length == 3);
+        check(as[1].getAnnotations().length == 0);
+
+        Annotation[] annos;
+        annos = as[0].getAnnotations();
+        check(annos.length == 2);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(annos[1].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno)annos[0]).value().equals("implements serializable"));
+        check(((TypeAnno2)annos[1]).value().equals("implements2 serializable"));
+
+        annos = as[2].getAnnotations();
+        check(annos.length == 2);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(annos[1].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno)annos[0]).value().equals("implements cloneable"));
+        check(((TypeAnno2)annos[1]).value().equals("implements2 cloneable"));
+    }
+
+    private static void testReturnType() throws Exception {
+        Method m = TestClassArray.class.getDeclaredMethod("foo", (Class<?>[])null);
+        Annotation[] annos = m.getAnnotatedReturnType().getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("return1"));
+    }
+
+    private static void testNested() throws Exception {
+        Method m = TestClassNested.class.getDeclaredMethod("foo", (Class<?>[])null);
+        Annotation[] annos = m.getAnnotatedReturnType().getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("array"));
+
+        AnnotatedType t = m.getAnnotatedReturnType();
+        t = ((AnnotatedArrayType)t).getAnnotatedGenericComponentType();
+        annos = t.getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("Inner"));
+    }
+
+    private static void testArray() throws Exception {
+        Method m = TestClassArray.class.getDeclaredMethod("foo", (Class<?>[])null);
+        AnnotatedArrayType t = (AnnotatedArrayType) m.getAnnotatedReturnType();
+        Annotation[] annos = t.getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("return1"));
+
+        t = (AnnotatedArrayType)t.getAnnotatedGenericComponentType();
+        annos = t.getAnnotations();
+        check(annos.length == 0);
+
+        t = (AnnotatedArrayType)t.getAnnotatedGenericComponentType();
+        annos = t.getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("return3"));
+
+        AnnotatedType tt = t.getAnnotatedGenericComponentType();
+        check(!(tt instanceof AnnotatedArrayType));
+        annos = tt.getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("return4"));
+    }
+
+    private static void testRunException() throws Exception {
+        Method m = TestClassException.class.getDeclaredMethod("foo", (Class<?>[])null);
+        AnnotatedType[] ts = m.getAnnotatedExceptionTypes();
+        check(ts.length == 3);
+
+        AnnotatedType t;
+        Annotation[] annos;
+        t = ts[0];
+        annos = t.getAnnotations();
+        check(annos.length == 2);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(annos[1].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno)annos[0]).value().equals("RE"));
+        check(((TypeAnno2)annos[1]).value().equals("RE2"));
+
+        t = ts[1];
+        annos = t.getAnnotations();
+        check(annos.length == 0);
+
+        t = ts[2];
+        annos = t.getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("AIOOBE"));
+    }
+
+    private static void testClassTypeVarBounds() throws Exception {
+        Method m = TestClassTypeVarAndField.class.getDeclaredMethod("foo", (Class<?>[])null);
+        AnnotatedType ret = m.getAnnotatedReturnType();
+        Annotation[] annos = ret.getAnnotations();
+        check(annos.length == 2);
+
+        AnnotatedType[] annotatedBounds = ((AnnotatedTypeVariable)ret).getAnnotatedBounds();
+        check(annotatedBounds.length == 2);
+
+        annos = annotatedBounds[0].getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("Object1"));
+
+        annos = annotatedBounds[1].getAnnotations();
+        check(annos.length == 2);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(annos[1].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno)annos[0]).value().equals("Runnable1"));
+        check(((TypeAnno2)annos[1]).value().equals("Runnable2"));
+    }
+
+    private static void testMethodTypeVarBounds() throws Exception {
+        Method m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo2", (Class<?>[])null);
+        AnnotatedType ret2 = m2.getAnnotatedReturnType();
+        AnnotatedType[] annotatedBounds2 = ((AnnotatedTypeVariable)ret2).getAnnotatedBounds();
+        check(annotatedBounds2.length == 1);
+
+        Annotation[] annos = annotatedBounds2[0].getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("M Runnable"));
+    }
+
+    private static void testFields() throws Exception {
+        Field f1 = TestClassTypeVarAndField.class.getDeclaredField("field1");
+        AnnotatedType at;
+        Annotation[] annos;
+
+        at = f1.getAnnotatedType();
+        annos = at.getAnnotations();
+        check(annos.length == 2);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(annos[1].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno)annos[0]).value().equals("T1 field"));
+        check(((TypeAnno2)annos[1]).value().equals("T2 field"));
+
+        Field f2 = TestClassTypeVarAndField.class.getDeclaredField("field2");
+        at = f2.getAnnotatedType();
+        annos = at.getAnnotations();
+        check(annos.length == 0);
+
+        Field f3 = TestClassTypeVarAndField.class.getDeclaredField("field3");
+        at = f3.getAnnotatedType();
+        annos = at.getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("Object field"));
+    }
+
+    private static void testClassTypeVar() throws Exception {
+        TypeVariable[] typeVars = TestClassTypeVarAndField.class.getTypeParameters();
+        Annotation[] annos;
+        check(typeVars.length == 2);
+
+        // First TypeVar
+        AnnotatedType[] annotatedBounds = typeVars[0].getAnnotatedBounds();
+        check(annotatedBounds.length == 2);
+
+        annos = annotatedBounds[0].getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("Object1"));
+
+        annos = annotatedBounds[1].getAnnotations();
+        check(annos.length == 2);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(annos[1].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno)annos[0]).value().equals("Runnable1"));
+        check(((TypeAnno2)annos[1]).value().equals("Runnable2"));
+
+        // second TypeVar regular anno
+        Annotation[] regularAnnos = typeVars[1].getAnnotations();
+        check(regularAnnos.length == 1);
+        check(typeVars[1].getAnnotation(TypeAnno.class).value().equals("EE"));
+
+        // second TypeVar
+        annotatedBounds = typeVars[1].getAnnotatedBounds();
+        check(annotatedBounds.length == 1);
+
+        annos = annotatedBounds[0].getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno2.class));
+        check(((TypeAnno2)annos[0]).value().equals("EEBound"));
+    }
+
+    private static void testMethodTypeVar() throws Exception {
+        Method m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo2", (Class<?>[])null);
+        TypeVariable[] t = m2.getTypeParameters();
+        check(t.length == 1);
+        Annotation[] annos = t[0].getAnnotations();
+        check(annos.length == 0);
+
+        AnnotatedType[] annotatedBounds2 = t[0].getAnnotatedBounds();
+        check(annotatedBounds2.length == 1);
+
+        annos = annotatedBounds2[0].getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("M Runnable"));
+
+        // Second method
+        m2 = TestClassTypeVarAndField.class.getDeclaredMethod("foo3", (Class<?>[])null);
+        t = m2.getTypeParameters();
+        check(t.length == 1);
+        annos = t[0].getAnnotations();
+        check(annos.length == 1);
+        check(annos[0].annotationType().equals(TypeAnno.class));
+        check(((TypeAnno)annos[0]).value().equals("K"));
+
+        annotatedBounds2 = t[0].getAnnotatedBounds();
+        check(annotatedBounds2.length == 1);
+
+        annos = annotatedBounds2[0].getAnnotations();
+        check(annos.length == 0);
+    }
+
+    private static void testParameterizedType() {
+        // Base
+        AnnotatedType[] as;
+        as = TestParameterizedType.class.getAnnotatedInterfaces();
+        check(as.length == 1);
+        check(as[0].getAnnotations().length == 1);
+        check(as[0].getAnnotation(TypeAnno.class).value().equals("M"));
+
+        Annotation[] annos;
+        as = ((AnnotatedParameterizedType)as[0]).getAnnotatedActualTypeArguments();
+        check(as.length == 2);
+        annos = as[0].getAnnotations();
+        check(annos.length == 1);
+        check(as[0].getAnnotation(TypeAnno.class).value().equals("S"));
+        check(as[0].getAnnotation(TypeAnno2.class) == null);
+
+        annos = as[1].getAnnotations();
+        check(annos.length == 2);
+        check(((TypeAnno)annos[0]).value().equals("I"));
+        check(as[1].getAnnotation(TypeAnno2.class).value().equals("I2"));
+    }
+
+    private static void testNestedParameterizedType() throws Exception {
+        Method m = TestParameterizedType.class.getDeclaredMethod("foo2", (Class<?>[])null);
+        AnnotatedType ret = m.getAnnotatedReturnType();
+        Annotation[] annos;
+        annos = ret.getAnnotations();
+        check(annos.length == 1);
+        check(((TypeAnno)annos[0]).value().equals("I"));
+
+        AnnotatedType[] args = ((AnnotatedParameterizedType)ret).getAnnotatedActualTypeArguments();
+        check(args.length == 1);
+        annos = args[0].getAnnotations();
+        check(annos.length == 2);
+        check(((TypeAnno)annos[0]).value().equals("I1"));
+        check(args[0].getAnnotation(TypeAnno2.class).value().equals("I2"));
+    }
+
+    private static void testWildcardType() throws Exception {
+        Method m = TestWildcardType.class.getDeclaredMethod("foo", (Class<?>[])null);
+        AnnotatedType ret = m.getAnnotatedReturnType();
+        AnnotatedType[] t;
+        t = ((AnnotatedParameterizedType)ret).getAnnotatedActualTypeArguments();
+        check(t.length == 1);
+        ret = t[0];
+
+        Field f = TestWildcardType.class.getDeclaredField("f1");
+        AnnotatedWildcardType w = (AnnotatedWildcardType)((AnnotatedParameterizedType)f
+            .getAnnotatedType()).getAnnotatedActualTypeArguments()[0];
+        t = w.getAnnotatedLowerBounds();
+        check(t.length == 0);
+        t = w.getAnnotatedUpperBounds();
+        check(t.length == 1);
+        Annotation[] annos;
+        annos = t[0].getAnnotations();
+        check(annos.length == 1);
+        check(((TypeAnno)annos[0]).value().equals("2"));
+
+        f = TestWildcardType.class.getDeclaredField("f2");
+        w = (AnnotatedWildcardType)((AnnotatedParameterizedType)f
+            .getAnnotatedType()).getAnnotatedActualTypeArguments()[0];
+        t = w.getAnnotatedUpperBounds();
+        check(t.length == 0);
+        t = w.getAnnotatedLowerBounds();
+        check(t.length == 1);
+    }
+}
+
+abstract class TestWildcardType {
+    public <T> List<? super T> foo() { return null;}
+    public Class<@TypeAnno("1") ? extends @TypeAnno("2") Annotation> f1;
+    public Class<@TypeAnno("3") ? super @TypeAnno("4") Annotation> f2;
+}
+
+abstract class TestParameterizedType implements @TypeAnno("M") Map<@TypeAnno("S")String, @TypeAnno("I") @TypeAnno2("I2")Integer> {
+    public ParameterizedOuter<String>.ParameterizedInner<Integer> foo() {return null;}
+    public @TypeAnno("O") ParameterizedOuter<@TypeAnno("S1") @TypeAnno2("S2") String>.
+               @TypeAnno("I") ParameterizedInner<@TypeAnno("I1") @TypeAnno2("I2")Integer> foo2() {
+        return null;
+    }
+}
+
+class ParameterizedOuter <T> {
+    class ParameterizedInner <U> {}
+}
+
+abstract class TestClassArray extends @TypeAnno("extends") @TypeAnno2("extends2") Object
+    implements @TypeAnno("implements serializable") @TypeAnno2("implements2 serializable") Serializable,
+    Readable,
+    @TypeAnno("implements cloneable") @TypeAnno2("implements2 cloneable") Cloneable {
+    public @TypeAnno("return4") Object @TypeAnno("return1") [][] @TypeAnno("return3")[] foo() { return null; }
+}
+
+abstract class TestClassNested {
+    public @TypeAnno("Outer") Outer.@TypeAnno("Inner")Inner @TypeAnno("array")[] foo() { return null; }
+}
+
+class Outer {
+    class Inner {
+    }
+}
+
+abstract class TestClassException {
+    public Object foo() throws @TypeAnno("RE") @TypeAnno2("RE2") RuntimeException,
+                                                                 NullPointerException,
+                                             @TypeAnno("AIOOBE") ArrayIndexOutOfBoundsException {
+        return null;
+    }
+}
+
+abstract class TestClassTypeVarAndField <T extends @TypeAnno("Object1") Object
+                                          & @TypeAnno("Runnable1") @TypeAnno2("Runnable2") Runnable,
+                                        @TypeAnno("EE")EE extends @TypeAnno2("EEBound") Runnable > {
+    @TypeAnno("T1 field") @TypeAnno2("T2 field") T field1;
+    T field2;
+    @TypeAnno("Object field") Object field3;
+
+    public @TypeAnno("t1") @TypeAnno2("t2") T foo(){ return null; }
+    public <M extends @TypeAnno("M Runnable") Runnable> M foo2() {return null;}
+    public <@TypeAnno("K") K extends Cloneable> K foo3() {return null;}
+}
+
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.RUNTIME)
+@interface TypeAnno {
+    String value();
+}
+
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.RUNTIME)
+@interface TypeAnno2 {
+    String value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/annotation/TypeParamAnnotation.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004698
+ * @summary Unit test for annotations on TypeVariables
+ */
+
+import java.util.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.io.Serializable;
+
+public class TypeParamAnnotation {
+    public static void main(String[] args) throws Exception {
+        testOnClass();
+        testOnMethod();
+        testGetAnno();
+        testGetAnnos();
+    }
+
+    private static void check(boolean b) {
+        if (!b)
+            throw new RuntimeException();
+    }
+
+    private static void testOnClass() {
+        TypeVariable<?>[] ts = TypeParam.class.getTypeParameters();
+        check(ts.length == 3);
+
+        Annotation[] as;
+
+        as = ts[0].getAnnotations();
+        check(as.length == 2);
+        check(((ParamAnno)as[0]).value().equals("t"));
+        check(((ParamAnno2)as[1]).value() == 1);
+
+        as = ts[1].getAnnotations();
+        check(as.length == 0);
+
+        as = ts[2].getAnnotations();
+        check(as.length == 2);
+        check(((ParamAnno)as[0]).value().equals("v"));
+        check(((ParamAnno2)as[1]).value() == 2);
+    }
+    private static void testOnMethod() throws Exception {
+        TypeVariable<?>[] ts = TypeParam.class.getDeclaredMethod("foo").getTypeParameters();
+        check(ts.length == 3);
+
+        Annotation[] as;
+
+        as = ts[0].getAnnotations();
+        check(as.length == 2);
+        check(((ParamAnno)as[0]).value().equals("x"));
+        check(((ParamAnno2)as[1]).value() == 3);
+
+        as = ts[1].getAnnotations();
+        check(as.length == 0);
+
+        as = ts[2].getAnnotations();
+        check(as.length == 2);
+        check(((ParamAnno)as[0]).value().equals("z"));
+        check(((ParamAnno2)as[1]).value() == 4);
+    }
+
+    private static void testGetAnno() {
+        TypeVariable<?>[] ts = TypeParam.class.getTypeParameters();
+        ParamAnno a;
+        a = ts[0].getAnnotation(ParamAnno.class);
+        check(a.value().equals("t"));
+    }
+    private static void testGetAnnos() throws Exception {
+        TypeVariable<?>[] ts = TypeParam.class.getDeclaredMethod("foo").getTypeParameters();
+        ParamAnno2[] as;
+        as = ts[0].getAnnotations(ParamAnno2.class);
+        check(as.length == 1);
+        check(as[0].value() == 3);
+    }
+}
+
+class TypeParam <@ParamAnno("t") @ParamAnno2(1) T,
+                 U,
+                 @ParamAnno("v") @ParamAnno2(2) V extends Runnable> {
+    public <@ParamAnno("x") @ParamAnno2(3) X,
+            Y,
+            @ParamAnno("z") @ParamAnno2(4) Z extends Cloneable> void foo() {}
+}
+
+@Target(ElementType.TYPE_PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+@interface ParamAnno {
+    String value();
+}
+
+@Target(ElementType.TYPE_PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+@interface ParamAnno2 {
+    int value();
+}
--- a/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/lang/annotation/repeatingAnnotations/RepeatedUnitTest.java	Tue Feb 05 11:11:53 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     7154390
+ * @bug     7154390 8005712
  * @summary Unit test for repeated annotation reflection
  *
  * @compile RepeatedUnitTest.java subpackage/package-info.java subpackage/Container.java subpackage/Containee.java subpackage/NonRepeated.java subpackage/InheritedContainee.java subpackage/InheritedContainer.java subpackage/InheritedNonRepeated.java
@@ -58,7 +58,7 @@
         checkMultiplier(Me1.class.getField("foo"), 1);
 
         // METHOD
-        checkMultiplier(Me1.class.getDeclaredMethod("mee", null), 100);
+        checkMultiplier(Me1.class.getDeclaredMethod("mee", (Class<?>[])null), 100);
 
         // INNER CLASS
         checkMultiplier(Me1.MiniMee.class, 1000);
@@ -84,8 +84,7 @@
 
     static void packageRepeated(AnnotatedElement e) {
         Containee c = e.getAnnotation(Containee.class);
-        check(c.value() == 1);
-
+        check(c == null);
         check(2 == countAnnotation(e, Containee.class));
 
         c = e.getAnnotations(Containee.class)[0];
@@ -93,7 +92,7 @@
         c = e.getAnnotations(Containee.class)[1];
         check(c.value() == 2);
 
-        check(2 == containsAnnotationOfType(e.getAnnotations(), Containee.class));
+        check(0 == containsAnnotationOfType(e.getAnnotations(), Containee.class));
     }
 
     static void packageContainer(AnnotatedElement e) {
@@ -161,14 +160,26 @@
     }
 
     static void checkMultiplier(AnnotatedElement e, int m) {
+        // Basic sanity of non-repeating getAnnotation(Class)
         check(e.getAnnotation(NonRepeated.class).value() == 5 * m);
 
+        // Check count of annotations returned from getAnnotations(Class)
         check(4 == countAnnotation(e, Containee.class));
         check(1 == countAnnotation(e, Container.class));
         check(1 == countAnnotation(e, NonRepeated.class));
 
+        // Check contents of array returned from getAnnotations(Class)
         check(e.getAnnotations(Containee.class)[2].value() == 3 * m);
         check(e.getAnnotations(NonRepeated.class)[0].value() == 5 * m);
+
+        // Check getAnnotation(Class)
+        check(e.getAnnotation(Containee.class) == null);
+        check(e.getAnnotation(Container.class) != null);
+
+        // Check count of annotations returned from getAnnotations()
+        check(0 == containsAnnotationOfType(e.getAnnotations(), Containee.class));
+        check(1 == containsAnnotationOfType(e.getAnnotations(), Container.class));
+        check(1 == containsAnnotationOfType(e.getAnnotations(), NonRepeated.class));
     }
 
     static void check(Boolean b) {
--- a/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/lang/annotation/repeatingAnnotations/subpackage/Containee.java	Tue Feb 05 11:11:53 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,7 +26,6 @@
 import java.lang.annotation.*;
 
 @Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(Container.class)
 @Repeatable(Container.class)
 public @interface Containee {
     int value();
--- a/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/lang/annotation/repeatingAnnotations/subpackage/Container.java	Tue Feb 05 11:11:53 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,7 +26,6 @@
 import java.lang.annotation.*;
 
 @Retention(RetentionPolicy.RUNTIME)
-@ContainerFor(Containee.class)
 public @interface Container {
     Containee[] value();
 }
--- a/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainee.java	Tue Feb 05 11:11:53 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,7 +27,6 @@
 
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
-@ContainedBy(InheritedContainer.class)
 @Repeatable(InheritedContainer.class)
 public @interface InheritedContainee {
     int value();
--- a/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/lang/annotation/repeatingAnnotations/subpackage/InheritedContainer.java	Tue Feb 05 11:11:53 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,7 +27,6 @@
 
 @Inherited
 @Retention(RetentionPolicy.RUNTIME)
-@ContainerFor(InheritedContainee.class)
 public @interface InheritedContainer {
     InheritedContainee[] value();
 }
--- a/test/java/lang/reflect/Parameter/WithoutParameters.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/lang/reflect/Parameter/WithoutParameters.java	Tue Feb 05 11:11:53 2013 -0800
@@ -23,163 +23,152 @@
 
 /*
  * @test
+ * @bug 8004729
  * @summary javac should generate method parameters correctly.
  */
 
 import java.lang.*;
 import java.lang.reflect.*;
+import java.lang.annotation.*;
 import java.util.List;
+import java.util.Objects;
+
+import static java.lang.annotation.ElementType.*;
 
 public class WithoutParameters {
+    int errors = 0;
 
-    private static final Class<?>[] qux_types = {
-        int.class,
-        Foo.class,
-        List.class,
-        List.class,
-        List.class,
-        String[].class
-    };
+    private WithoutParameters() {}
 
     public static void main(String argv[]) throws Exception {
-        int error = 0;
-        Method[] methods = Foo.class.getMethods();
-        for(Method m : methods) {
-            System.err.println("Inspecting method " + m);
-            Parameter[] parameters = m.getParameters();
-            if(parameters == null)
-                throw new Exception("getParameters should never be null");
-            for(int i = 0; i < parameters.length; i++) {
-                    Parameter p = parameters[i];
-                    if(!p.getDeclaringExecutable().equals(m)) {
-                        System.err.println(p + ".getDeclaringExecutable != " + m);
-                        error++;
-                    }
-                    if(null == p.getType()) {
-                        System.err.println(p + ".getType() == null");
-                        error++;
-                    }
-                    if(null == p.getParameterizedType()) {
-                        System.err.println(p + ".getParameterizedType == null");
-                        error++;
-                    }
-            }
-            if(m.getName().equals("qux")) {
-                if(6 != parameters.length) {
-                    System.err.println("Wrong number of parameters for qux");
-                    error++;
-                }
-                for(int i = 0; i < parameters.length; i++) {
-                    Parameter p = parameters[i];
-                    // The getType family work with or without
-                    // parameter attributes compiled in.
-                    if(!parameters[i].getType().equals(qux_types[i])) {
-                        System.err.println("Wrong parameter type for " + parameters[0] + ": expected " + qux_types[i] + ", but got " + parameters[i].getType());
-                        error++;
+        WithoutParameters wp = new WithoutParameters();
+        wp.runTests(Foo.class.getMethods());
+        wp.runTests(Foo.Inner.class.getConstructors());
+        wp.checkForErrors();
+    }
+
+    void runTests(Method[] methods) throws Exception {
+        for(Method m : methods) {runTest(m);}
+    }
+
+    void runTests(Constructor[] constructors) throws Exception {
+        for(Constructor c : constructors) {runTest(c);}
+    }
+
+    void runTest(Executable e) throws Exception {
+        System.err.println("Inspecting executable " + e);
+        Parameter[] parameters = e.getParameters();
+        Objects.requireNonNull(parameters, "getParameters should never be null");
+
+        ExpectedParameterInfo epi = e.getAnnotation(ExpectedParameterInfo.class);
+        if (epi != null) {
+            abortIfTrue(epi.parameterCount() != e.getParameterCount(), "Bad parameter count for "+ e);
+            abortIfTrue(epi.isVarArgs() != e.isVarArgs(),"Bad varargs value for "+ e);
+        }
+        abortIfTrue(e.getParameterCount() != parameters.length, "Mismatched of parameter counts.");
+
+        for(int i = 0; i < parameters.length; i++) {
+            Parameter p = parameters[i];
+            errorIfTrue(!p.getDeclaringExecutable().equals(e), p + ".getDeclaringExecutable != " + e);
+            Objects.requireNonNull(p.getType(), "getType() should not be null");
+            Objects.requireNonNull(p.getParameterizedType(), "getParameterizedType() should not be null");
+
+            if (epi != null) {
+                Class<?> expectedParameterType = epi.parameterTypes()[i];
+                errorIfTrue(!p.getType().equals(expectedParameterType),
+                            "Wrong parameter type for " + p + ": expected " + expectedParameterType  +
+                            ", but got " + p.getType());
+
+                ParameterizedInfo[] expectedParameterizedTypes = epi.parameterizedTypes();
+                if (expectedParameterizedTypes.length > 0) {
+                    Type parameterizedType = p.getParameterizedType();
+                    Class<? extends Type> expectedParameterziedTypeType = expectedParameterizedTypes[i].value();
+                    errorIfTrue(!expectedParameterziedTypeType.isAssignableFrom(parameterizedType.getClass()),
+                                "Wrong class of parameteried type of " + p + ": expected " + expectedParameterziedTypeType  +
+                                ", but got " + parameterizedType.getClass());
+
+                    if (expectedParameterziedTypeType.equals(Class.class)) {
+                        errorIfTrue(!parameterizedType.equals(expectedParameterType),
+                                    "Wrong parameteried type for " + p + ": expected " + expectedParameterType  +
+                                    ", but got " + parameterizedType);
+                    } else {
+                        if (expectedParameterziedTypeType.equals(ParameterizedType.class)) {
+                            ParameterizedType ptype = (ParameterizedType)parameterizedType;
+                            errorIfTrue(!ptype.getRawType().equals(expectedParameterType),
+                                        "Wrong raw type for " + p + ": expected " + expectedParameterType  +
+                                        ", but got " + ptype.getRawType());
+                        }
+
+                        // Check string representation
+                        String expectedStringOfType = epi.parameterizedTypes()[i].string();
+                        errorIfTrue(!expectedStringOfType.equals(parameterizedType.toString()),
+                                    "Bad type string" + p + ": expected " + expectedStringOfType  +
+                                    ", but got " + parameterizedType.toString());
                     }
                 }
-                if(!parameters[0].getParameterizedType().equals(int.class)) {
-                    System.err.println("getParameterizedType for quux is wrong");
-                    error++;
-                }
-                if(!parameters[1].getParameterizedType().equals(Foo.class)) {
-                    System.err.println("getParameterizedType for quux is wrong");
-                    error++;
-                }
-                if(!(parameters[2].getParameterizedType() instanceof
-                     ParameterizedType)) {
-                    System.err.println("getParameterizedType for l is wrong");
-                    error++;
-                } else {
-                    ParameterizedType pt =
-                        (ParameterizedType) parameters[2].getParameterizedType();
-                    if(!pt.getRawType().equals(List.class)) {
-                        System.err.println("Raw type for l is wrong");
-                        error++;
-                    }
-                    if(1 != pt.getActualTypeArguments().length) {
-                        System.err.println("Number of type parameters for l is wrong");
-                        error++;
-                    }
-                    if(!(pt.getActualTypeArguments()[0] instanceof WildcardType)) {
-                        System.err.println("Type parameter for l is wrong");
-                        error++;
-                    }
-                }
-                if(!(parameters[3].getParameterizedType() instanceof
-                     ParameterizedType)) {
-                    System.err.println("getParameterizedType for l2 is wrong");
-                    error++;
-                } else {
-                    ParameterizedType pt =
-                        (ParameterizedType) parameters[3].getParameterizedType();
-                    if(!pt.getRawType().equals(List.class)) {
-                        System.err.println("Raw type for l2 is wrong");
-                        error++;
-                    }
-                    if(1 != pt.getActualTypeArguments().length) {
-                        System.err.println("Number of type parameters for l2 is wrong");
-                        error++;
-                    }
-                    if(!(pt.getActualTypeArguments()[0].equals(Foo.class))) {
-                        System.err.println("Type parameter for l2 is wrong");
-                        error++;
-                    }
-                }
-                if(!(parameters[4].getParameterizedType() instanceof
-                     ParameterizedType)) {
-                    System.err.println("getParameterizedType for l3 is wrong");
-                    error++;
-                } else {
-                    ParameterizedType pt =
-                        (ParameterizedType) parameters[4].getParameterizedType();
-                    if(!pt.getRawType().equals(List.class)) {
-                        System.err.println("Raw type for l3 is wrong");
-                        error++;
-                    }
-                    if(1 != pt.getActualTypeArguments().length) {
-                        System.err.println("Number of type parameters for l3 is wrong");
-                        error++;
-                    }
-                    if(!(pt.getActualTypeArguments()[0] instanceof WildcardType)) {
-                        System.err.println("Type parameter for l3 is wrong");
-                        error++;
-                    } else {
-                        WildcardType wt = (WildcardType)
-                            pt.getActualTypeArguments()[0];
-                        if(!wt.getUpperBounds()[0].equals(Foo.class)) {
-                            System.err.println("Upper bounds on type parameter fol l3 is wrong");
-                            error++;
-                        }
-                    }
-                }
-                if(!parameters[5].isVarArgs()) {
-                    System.err.println("isVarArg for rest is wrong");
-                    error++;
-                }
-                if(!(parameters[5].getParameterizedType().equals(String[].class))) {
-                    System.err.println("getParameterizedType for rest is wrong");
-                    error++;
-                }
-
             }
         }
-        if(0 != error)
-            throw new Exception("Failed " + error + " tests");
+    }
+
+    private void checkForErrors() {
+        if (errors > 0)
+            throw new RuntimeException("Failed " + errors + " tests");
+    }
+
+    private void errorIfTrue(boolean predicate, String errMessage) {
+        if (predicate) {
+            errors++;
+            System.err.println(errMessage);
+        }
+    }
+
+    private void abortIfTrue(boolean predicate, String errMessage) {
+        if (predicate) {
+            throw new RuntimeException(errMessage);
+        }
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({METHOD, CONSTRUCTOR})
+    @interface ExpectedParameterInfo {
+        int parameterCount() default 0;
+        Class<?>[] parameterTypes() default {};
+        ParameterizedInfo[] parameterizedTypes() default {};
+        boolean isVarArgs() default false;
+    }
+
+    @Target({})
+    @interface ParameterizedInfo {
+        Class<? extends Type> value() default Class.class;
+        String string() default "";
     }
 
     public class Foo {
         int thing;
+        @ExpectedParameterInfo(parameterCount = 6,
+                               parameterTypes =
+                               {int.class, Foo.class,
+                                List.class, List.class,
+                                List.class, String[].class},
+                               parameterizedTypes =
+                                {@ParameterizedInfo(Class.class),
+                                 @ParameterizedInfo(Class.class),
+                                 @ParameterizedInfo(value=ParameterizedType.class, string="java.util.List<?>"),
+                                 @ParameterizedInfo(value=ParameterizedType.class, string="java.util.List<WithoutParameters$Foo>"),
+                                 @ParameterizedInfo(value=ParameterizedType.class, string="java.util.List<? extends WithoutParameters$Foo>"),
+                                 @ParameterizedInfo(Class.class)},
+                               isVarArgs = true)
         public void qux(int quux, Foo quuux,
                         List<?> l, List<Foo> l2,
                         List<? extends Foo> l3,
                         String... rest) {}
         public class Inner {
             int thang;
+            @ExpectedParameterInfo(parameterCount = 2,
+                                   parameterTypes = {Foo.class, int.class})
             public Inner(int theng) {
                 thang = theng + thing;
             }
         }
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/net/Socket/asyncClose/Race.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8006395
+ * @summary Race in async socket close on Linux
+ */
+
+import java.io.InputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.concurrent.Phaser;
+
+// Racey test, will not always fail, but if it does then we have a problem.
+
+public class Race {
+    final static int THREADS = 100;
+
+    public static void main(String[] args) throws Exception {
+        try (ServerSocket ss = new ServerSocket(0)) {
+            final int port = ss.getLocalPort();
+            final Phaser phaser = new Phaser(THREADS + 1);
+            for (int i=0; i<100; i++) {
+                final Socket s = new Socket("localhost", port);
+                s.setSoLinger(false, 0);
+                try (Socket sa = ss.accept()) {
+                    sa.setSoLinger(false, 0);
+                    final InputStream is = s.getInputStream();
+                    Thread[] threads = new Thread[THREADS];
+                    for (int j=0; j<THREADS; j++) {
+                        threads[j] = new Thread() {
+                        public void run() {
+                            try {
+                                phaser.arriveAndAwaitAdvance();
+                                while (is.read() != -1)
+                                    Thread.sleep(50);
+                            } catch (Exception x) {
+                                if (!(x instanceof SocketException
+                                      && x.getMessage().equals("Socket closed")))
+                                    x.printStackTrace();
+                                // ok, expect Socket closed
+                            }
+                        }};
+                    }
+                    for (int j=0; j<100; j++)
+                        threads[j].start();
+                    phaser.arriveAndAwaitAdvance();
+                    s.close();
+                    for (int j=0; j<100; j++)
+                        threads[j].join();
+                }
+            }
+        }
+    }
+}
--- a/test/java/net/URL/Constructor.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/net/URL/Constructor.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2002, 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
@@ -21,71 +21,235 @@
  * questions.
  */
 
-/* This is no longer run directly. See runconstructor.sh
- *
- *
- *
+/*
+ * @test
+ * @bug 4393671
+ * @summary URL constructor URL(URL context, String spec) FAILED with specific input
+ */
+
+/*
  * This program tests the URL parser in the URL constructor. It
  * tries to construct a variety of valid URLs with a given context
  * (which may be null) and a variety of specs. It then compares the
  * result with an expected value.
- *
- * It expects that a data file named "urls" be available in the
- * current directory, from which it will get its testing data. The
- * format of the file is:
- *
- * URL: null
- * spec: jar:http://www.foo.com/dir1/jar.jar!/
- * expected: jar:http://www.foo.com/dir1/jar.jar!/
- *
- * where URL is the context, spec is the spec and expected is the
- * expected result. The first : must be followed by a space. Each test
- * entry should be followed by a blank line.
  */
 
-import java.io.*;
+import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 public class Constructor {
 
     public static void main(String[] args) throws Exception {
-        URL url = null;
-        String urls = "jar_urls";
-        if (args.length > 0 && args[0] != null) {
-            urls = args[0];
-        }
+        List<Entry> entries = new ArrayList<>();
+        entries.addAll(Arrays.asList(fileURLs));
+        entries.addAll(Arrays.asList(jarURLs));
+        entries.addAll(Arrays.asList(normalHttpURLs));
+        entries.addAll(Arrays.asList(abnormalHttpURLs));
+        if (hasFtp())
+            entries.addAll(Arrays.asList(ftpURLs));
+        URL url;
 
-        File f = new File(urls);
-        InputStream file = new FileInputStream(f);
-        BufferedReader in = new BufferedReader(new InputStreamReader(file));
-        while(true) {
-            String context = in.readLine();
-            if (context == null) {
-                break;
-            }
-            context = getValue(context);
-            String spec = getValue(in.readLine());
-            String expected = getValue(in.readLine());
+        for (Entry e : entries) {
+            if (e.context == null)
+                url = new URL(e.spec);
+            else
+                url = new URL(new URL(e.context), e.spec);
 
-            if (context.equals("null")) {
-                url = new URL(spec);
-            } else {
-                url = new URL(new URL(context), spec);
-            }
-            if (!(url.toString().equals(expected))) {
-                throw new RuntimeException("error for: \n\tURL:" + context +
-                                           "\n\tspec: " + spec +
-                                           "\n\texpected: " + expected +
+            if (!(url.toString().equals(e.expected))) {
+                throw new RuntimeException("error for: \n\tURL:" + e.context +
+                                           "\n\tspec: " + e.spec +
+                                           "\n\texpected: " + e.expected +
                                            "\n\tactual: " + url.toString());
             } else {
-                System.out.println("success for: " + url + "\n");
+                //debug
+                //System.out.println("success for: " + url);
             }
-            in.readLine();
         }
-        in.close();
     }
 
-    private static String getValue(String value) {
-        return value.substring(value.indexOf(':') + 2);
+    private static boolean hasFtp() {
+        try {
+            return new java.net.URL("ftp://") != null;
+        } catch (java.net.MalformedURLException x) {
+            System.out.println("FTP not supported by this runtime.");
+            return false;
+        }
     }
+
+    static class Entry {
+        final String context;
+        final String spec;
+        final String expected;
+        Entry(String context, String spec, String expected) {
+            this.context = context;
+            this.spec =spec;
+            this.expected = expected;
+        }
+    }
+
+    static Entry[] fileURLs = new Entry[] {
+        new Entry(null,
+                  "file://JavaSoft/Test",
+                  "file://JavaSoft/Test"),
+        new Entry(null,
+                  "file:///JavaSoft/Test",
+                  "file:/JavaSoft/Test"),
+        new Entry(null,
+                  "file:/JavaSoft/Test",
+                  "file:/JavaSoft/Test"),
+        new Entry(null,
+                  "file:/c:/JavaSoft/Test",
+                  "file:/c:/JavaSoft/Test"),
+        new Entry(null,
+                  "file:/c:/JavaSoft/Test:something",
+                  "file:/c:/JavaSoft/Test:something"),
+        new Entry(null,
+                  "file:/c:/JavaSoft/Test#anchor",
+                  "file:/c:/JavaSoft/Test#anchor"),
+        new Entry("file://JavaSoft/Test",
+                  "Test#bar",
+                  "file://JavaSoft/Test#bar"),
+        new Entry("file://codrus/c:/jdk/eng/index.html",
+                  "pulsar.html",
+                  "file://codrus/c:/jdk/eng/pulsar.html"),
+        new Entry("file:///c:/jdk/eng/index.html",
+                  "pulsar.html",
+                  "file:/c:/jdk/eng/pulsar.html"),
+        new Entry("file:///jdk/eng/index.html",
+                  "pulsar.html",
+                  "file:/jdk/eng/pulsar.html"),
+        new Entry("file://JavaSoft/Test",
+                  "file://radartoad.com/Test#bar",
+                  "file://radartoad.com/Test#bar"),
+        new Entry("file://JavaSoft/Test",
+                  "/c:/Test#bar",
+                  "file://JavaSoft/c:/Test#bar"),
+    };
+
+    static Entry[] jarURLs = new Entry[] {
+        new Entry(null,
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt"),
+        new Entry(null,
+                  "jar:http://www.foo.com/dir1/jar.jar!/",
+                  "jar:http://www.foo.com/dir1/jar.jar!/"),
+        new Entry(null,
+                  "jar:http://www.foo.com/dir1/jar.jar!/",
+                  "jar:http://www.foo.com/dir1/jar.jar!/"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "dir1/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "/dir1/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/dir1/",
+                  "entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/dir2/dir3/entry2.txt",
+                  "/dir1/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "/dir1/foo/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/",
+                  "dir4/foo/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/dir4/foo/entry.txt"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/",
+                  "/dir1/foo/entry.txt",
+                  "jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt"),
+        new Entry(null,
+                  "jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor",
+                  "jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/foo.txt",
+                  "#anchor",
+                  "jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor"),
+        new Entry("jar:http://www.foo.com/dir1/jar.jar!/foo/bar/",
+                  "baz/quux#anchor",
+                  "jar:http://www.foo.com/dir1/jar.jar!/foo/bar/baz/quux#anchor"),
+        new Entry("jar:http://balloo.com/olle.jar!/",
+                  "p2",
+                  "jar:http://balloo.com/olle.jar!/p2")
+    };
+
+    static Entry[] normalHttpURLs = new Entry[] {
+        new Entry("http://a/b/c/d;p?q", "g",       "http://a/b/c/g"),
+        new Entry("http://a/b/c/d;p?q", "./g",     "http://a/b/c/g"),
+        new Entry("http://a/b/c/d;p?q", "g/",      "http://a/b/c/g/"),
+        new Entry("http://a/b/c/d;p?q", "/g",      "http://a/g"),
+        new Entry("http://a/b/c/d;p?q", "//g",     "http://g"),
+        new Entry("http://a/b/c/d;p?q", "?y",      "http://a/b/c/?y"),
+        new Entry("http://a/b/c/d;p?q", "g?y",     "http://a/b/c/g?y"),
+        new Entry("http://a/b/c/d;p?q", "g#s",     "http://a/b/c/g#s"),
+        new Entry("http://a/b/c/d;p?q", "g?y#s",   "http://a/b/c/g?y#s"),
+        new Entry("http://a/b/c/d;p?q", ";x",      "http://a/b/c/;x"),
+        new Entry("http://a/b/c/d;p?q", "g;x",     "http://a/b/c/g;x"),
+        new Entry("http://a/b/c/d;p?q", "g;x?y#s", "http://a/b/c/g;x?y#s"),
+        new Entry("http://a/b/c/d;p?q", ".",       "http://a/b/c/"),
+        new Entry("http://a/b/c/d;p?q", "./",      "http://a/b/c/"),
+        new Entry("http://a/b/c/d;p?q", "..",      "http://a/b/"),
+        new Entry("http://a/b/c/d;p?q", "../",     "http://a/b/"),
+        new Entry("http://a/b/c/d;p?q", "../g",    "http://a/b/g"),
+        new Entry("http://a/b/c/d;p?q", "../..",   "http://a/"),
+        new Entry("http://a/b/c/d;p?q", "../../",  "http://a/"),
+        new Entry("http://a/b/c/d;p?q", "../../g", "http://a/g"),
+        new Entry(null,
+                  "http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc",
+                  "http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc")
+    };
+
+    static Entry[] abnormalHttpURLs = new Entry[] {
+        new Entry("http://a/b/c/d;p?q", "../../../g",    "http://a/../g"),
+        new Entry("http://a/b/c/d;p?q", "../../../../g", "http://a/../../g"),
+        new Entry("http://a/b/c/d;p?q", "/./g",          "http://a/./g"),
+        new Entry("http://a/b/c/d;p?q", "/../g",         "http://a/../g"),
+        new Entry("http://a/b/c/d;p?q", ".g",            "http://a/b/c/.g"),
+        new Entry("http://a/b/c/d;p?q", "g.",            "http://a/b/c/g."),
+        new Entry("http://a/b/c/d;p?q", "./../g",        "http://a/b/g"),
+        new Entry("http://a/b/c/d;p?q", "./g/.",         "http://a/b/c/g/"),
+        new Entry("http://a/b/c/d;p?q", "g/./h",         "http://a/b/c/g/h"),
+        new Entry("http://a/b/c/d;p?q", "g;x=1/./y",     "http://a/b/c/g;x=1/y"),
+        new Entry("http://a/b/c/d;p?q", "g;x=1/../y",    "http://a/b/c/y")
+    };
+
+    static Entry[] ftpURLs = new Entry[] {
+        new Entry(null,
+                  "ftp://ftp.foo.com/dir1/entry.txt",
+                  "ftp://ftp.foo.com/dir1/entry.txt"),
+        new Entry(null,
+                  "ftp://br:pwd@ftp.foo.com/dir1/jar.jar",
+                  "ftp://br:pwd@ftp.foo.com/dir1/jar.jar"),
+        new Entry("ftp://ftp.foo.com/dir1/foo.txt",
+                  "bar.txt",
+                  "ftp://ftp.foo.com/dir1/bar.txt"),
+        new Entry("ftp://ftp.foo.com/dir1/jar.jar",
+                  "/entry.txt",
+                  "ftp://ftp.foo.com/entry.txt"),
+        new Entry("ftp://ftp.foo.com/dir1/jar.jar",
+                  "dir1/entry.txt",
+                  "ftp://ftp.foo.com/dir1/dir1/entry.txt"),
+        new Entry("ftp://ftp.foo.com/dir1/jar.jar",
+                  "/dir1/entry.txt",
+                  "ftp://ftp.foo.com/dir1/entry.txt"),
+        new Entry("ftp://br:pwd@ftp.foo.com/dir1/jar.jar",
+                  "/dir1/entry.txt",
+                  "ftp://br:pwd@ftp.foo.com/dir1/entry.txt")
+    };
 }
--- a/test/java/net/URL/HandlerLoop.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/net/URL/HandlerLoop.java	Tue Feb 05 11:11:53 2013 -0800
@@ -36,7 +36,7 @@
     public static void main(String args[]) throws Exception {
         URL.setURLStreamHandlerFactory(
             new HandlerFactory("sun.net.www.protocol"));
-        URL url = new URL("file://bogus/index.html");
+        URL url = new URL("file:///bogus/index.html");
         System.out.println("url = " + url);
         url.openConnection();
     }
--- a/test/java/net/URL/Test.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/net/URL/Test.java	Tue Feb 05 11:11:53 2013 -0800
@@ -310,7 +310,14 @@
         throw new RuntimeException("Test failed");
     }
 
-
+    private static boolean hasFtp() {
+        try {
+            return new java.net.URL("ftp://") != null;
+        } catch (java.net.MalformedURLException x) {
+            System.out.println("FTP not supported by this runtime.");
+            return false;
+        }
+    }
 
     // -- Tests --
 
@@ -319,8 +326,9 @@
 
         header("RFC2396: Basic examples");
 
-        test("ftp://ftp.is.co.za/rfc/rfc1808.txt")
-            .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z();
+        if (hasFtp())
+            test("ftp://ftp.is.co.za/rfc/rfc1808.txt")
+                .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z();
 
         test("http://www.math.uio.no/faq/compression-faq/part1.html")
             .s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z();
@@ -328,8 +336,9 @@
         test("http://www.w3.org/Addressing/")
             .s("http").h("www.w3.org").p("/Addressing/").z();
 
-        test("ftp://ds.internic.net/rfc/")
-            .s("ftp").h("ds.internic.net").p("/rfc/").z();
+        if (hasFtp())
+            test("ftp://ds.internic.net/rfc/")
+                .s("ftp").h("ds.internic.net").p("/rfc/").z();
 
         test("http://www.ics.uci.edu/pub/ietf/url/historical.html#WARNING")
             .s("http").h("www.ics.uci.edu").p("/pub/ietf/url/historical.html")
--- a/test/java/net/URL/URIToURLTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/net/URL/URIToURLTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -28,20 +28,22 @@
  */
 
 import java.net.*;
+import java.util.ArrayList;
+import java.util.List;
 
 public class URIToURLTest {
     public static void main(String args[]) throws Exception {
-        String[] uris = {
-           "http://jag:cafebabe@java.sun.com:94/b/c/d?q#g",
-           "http://[1080:0:0:0:8:800:200C:417A]/index.html",
-           "http://a/b/c/d;p?q",
-           "ftp://ftp.is.co.za/rfc/rfc1808.txt",
-           "mailto:mduerst@ifi.unizh.ch", // opaque url
-           "http:comp.infosystems.www.servers.unix" //opaque url
-        };
+        List<String> uris = new ArrayList<>();
+        uris.add("http://jag:cafebabe@java.sun.com:94/b/c/d?q#g");
+        uris.add("http://[1080:0:0:0:8:800:200C:417A]/index.html");
+        uris.add("http://a/b/c/d;p?q");
+        uris.add("mailto:mduerst@ifi.unizh.ch");
+        uris.add("http:comp.infosystems.www.servers.unix");
+        if (hasFtp())
+            uris.add("ftp://ftp.is.co.za/rfc/rfc1808.txt");
 
-        for (int i = 0; i < uris.length; i++) {
-            URI uri = new URI(uris[i]);
+        for (String uriStr : uris) {
+            URI uri = new URI(uriStr);
             URL url = uri.toURL();
             String scheme = uri.getScheme();
             boolean schemeCheck = scheme == null? url.getProtocol() == null :
@@ -111,4 +113,13 @@
                                                url.getRef());
         }
     }
+
+    private static boolean hasFtp() {
+        try {
+            return new java.net.URL("ftp://") != null;
+        } catch (java.net.MalformedURLException x) {
+            System.out.println("FTP not supported by this runtime.");
+            return false;
+        }
+    }
 }
--- a/test/java/net/URL/abnormal_http_urls	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-URL: http://a/b/c/d;p?q
-spec: ../../../g
-expected: http://a/../g
-
-URL: http://a/b/c/d;p?q
-spec: ../../../../g
-expected: http://a/../../g
-
-URL: http://a/b/c/d;p?q
-spec: /./g
-expected: http://a/./g
-
-URL: http://a/b/c/d;p?q
-spec: /../g
-expected: http://a/../g
-
-URL: http://a/b/c/d;p?q
-spec: .g
-expected: http://a/b/c/.g
-
-URL: http://a/b/c/d;p?q
-spec: g.
-expected: http://a/b/c/g.
-
-URL: http://a/b/c/d;p?q
-spec: ./../g
-expected: http://a/b/g
-
-URL: http://a/b/c/d;p?q
-spec: ./g/.
-expected: http://a/b/c/g/
-
-URL: http://a/b/c/d;p?q
-spec: g/./h
-expected: http://a/b/c/g/h
-
-URL: http://a/b/c/d;p?q
-spec: g;x=1/./y
-expected: http://a/b/c/g;x=1/y
-
-URL: http://a/b/c/d;p?q
-spec: g;x=1/../y
-expected: http://a/b/c/y
--- a/test/java/net/URL/ftp_urls	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-URL: null
-spec: ftp://ftp.foo.com/dir1/entry.txt
-expected: ftp://ftp.foo.com/dir1/entry.txt
-
-URL: null
-spec: ftp://br:pwd@ftp.foo.com/dir1/jar.jar
-expected: ftp://br:pwd@ftp.foo.com/dir1/jar.jar
-
-URL: ftp://ftp.foo.com/dir1/foo.txt
-spec: bar.txt
-expected: ftp://ftp.foo.com/dir1/bar.txt
-
-URL: ftp://ftp.foo.com/dir1/jar.jar
-spec: /entry.txt
-expected: ftp://ftp.foo.com/entry.txt
-
-URL: ftp://ftp.foo.com/dir1/jar.jar
-spec: dir1/entry.txt
-expected: ftp://ftp.foo.com/dir1/dir1/entry.txt
-
-URL: ftp://ftp.foo.com/dir1/jar.jar
-spec: /dir1/entry.txt
-expected: ftp://ftp.foo.com/dir1/entry.txt
-
-URL: ftp://br:pwd@ftp.foo.com/dir1/jar.jar
-spec: /dir1/entry.txt
-expected: ftp://br:pwd@ftp.foo.com/dir1/entry.txt
--- a/test/java/net/URL/jar_urls	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-URL: null
-spec: jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir2/entry.txt
-
-URL: null
-spec: jar:http://www.foo.com/dir1/jar.jar!/
-expected: jar:http://www.foo.com/dir1/jar.jar!/
-
-URL: null
-spec: jar:http://www.foo.com/dir1/jar.jar!/
-expected: jar:http://www.foo.com/dir1/jar.jar!/
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: /entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: dir1/entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: /dir1/entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: /entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: /entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/dir1/
-spec: entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/dir2/dir3/entry2.txt
-spec: /dir1/entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: /dir1/foo/entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/
-spec: dir4/foo/entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/dir2/dir3/dir4/foo/entry.txt
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/
-spec: /dir1/foo/entry.txt
-expected: jar:http://www.foo.com/dir1/jar.jar!/dir1/foo/entry.txt
-
-URL: null
-spec: jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor
-expected: jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/foo.txt
-spec: #anchor
-expected: jar:http://www.foo.com/dir1/jar.jar!/foo.txt#anchor
-
-URL: jar:http://www.foo.com/dir1/jar.jar!/foo/bar/
-spec: baz/quux#anchor
-expected: jar:http://www.foo.com/dir1/jar.jar!/foo/bar/baz/quux#anchor
-
-URL: jar:http://balloo.com/olle.jar!/
-spec: p2
-expected: jar:http://balloo.com/olle.jar!/p2
--- a/test/java/net/URL/normal_http_urls	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-URL: http://a/b/c/d;p?q
-spec: g
-expected: http://a/b/c/g
-
-URL: http://a/b/c/d;p?q
-spec: ./g
-expected: http://a/b/c/g
-
-URL: http://a/b/c/d;p?q
-spec: g/
-expected: http://a/b/c/g/
-
-URL: http://a/b/c/d;p?q
-spec: /g
-expected: http://a/g
-
-URL: http://a/b/c/d;p?q
-spec: //g
-expected: http://g
-
-URL: http://a/b/c/d;p?q
-spec: ?y
-expected: http://a/b/c/?y
-
-URL: http://a/b/c/d;p?q
-spec: g?y
-expected: http://a/b/c/g?y
-
-URL: http://a/b/c/d;p?q
-spec: g#s
-expected: http://a/b/c/g#s
-
-URL: http://a/b/c/d;p?q
-spec: g?y#s
-expected: http://a/b/c/g?y#s
-
-URL: http://a/b/c/d;p?q
-spec: ;x
-expected: http://a/b/c/;x
-
-URL: http://a/b/c/d;p?q
-spec: g;x
-expected: http://a/b/c/g;x
-
-URL: http://a/b/c/d;p?q
-spec: g;x?y#s
-expected: http://a/b/c/g;x?y#s
-
-URL: http://a/b/c/d;p?q
-spec: .
-expected: http://a/b/c/
-
-URL: http://a/b/c/d;p?q
-spec: ./
-expected: http://a/b/c/
-
-URL: http://a/b/c/d;p?q
-spec: ..
-expected: http://a/b/
-
-URL: http://a/b/c/d;p?q
-spec: ../
-expected: http://a/b/
-
-URL: http://a/b/c/d;p?q
-spec: ../g
-expected: http://a/b/g
-
-URL: http://a/b/c/d;p?q
-spec: ../..
-expected: http://a/
-
-URL: http://a/b/c/d;p?q
-spec: ../../
-expected: http://a/
-
-URL: http://a/b/c/d;p?q
-spec: ../../g
-expected: http://a/g
-
-URL: null
-spec: http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc
-expected: http://www.javasoft.com/jdc/community/chat/index.html#javalive?frontpage-jdc
--- a/test/java/net/URL/runconstructor.sh	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-#
-# Copyright (c) 2000, 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 4393671
-# @summary URL constructor URL(URL context, String spec) FAILED with specific input in merlin
-#
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin )
-    PS=":"
-    FS="/"
-    ;;
-  CYGWIN* )
-    PS=";"
-    FS="/"
-    ;;
-  Windows* )
-    PS=";"
-    FS="\\"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . \
-    ${TESTSRC}${FS}Constructor.java
-
-failures=0
-
-go() {
-    echo ''
-    ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} Constructor $1
-    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-}
-
-go ${TESTSRC}${FS}share_file_urls
-go ${TESTSRC}${FS}jar_urls
-go ${TESTSRC}${FS}normal_http_urls
-go ${TESTSRC}${FS}ftp_urls
-go ${TESTSRC}${FS}abnormal_http_urls
-
-if [ "$failures" != "0" ]; then
-    echo $failures tests failed
-    exit 1;
-fi
--- a/test/java/net/URL/share_file_urls	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-URL: null
-spec: file://JavaSoft/Test
-expected: file://JavaSoft/Test
-
-URL: null
-spec: file:///JavaSoft/Test
-expected: file:/JavaSoft/Test
-
-URL: null
-spec: file:/JavaSoft/Test
-expected: file:/JavaSoft/Test
-
-URL: null
-spec: file:/c:/JavaSoft/Test
-expected: file:/c:/JavaSoft/Test
-
-URL: null
-spec: file:/c:/JavaSoft/Test:something
-expected: file:/c:/JavaSoft/Test:something
-
-URL: null
-spec: file:/c:/JavaSoft/Test#anchor
-expected: file:/c:/JavaSoft/Test#anchor
-
-URL: null
-spec: file:/JavaSoft/Test
-expected: file:/JavaSoft/Test
-
-URL: file://JavaSoft/Test
-spec: Test#bar
-expected: file://JavaSoft/Test#bar
-
-URL: file://codrus/c:/jdk/eng/index.html
-spec: pulsar.html
-expected: file://codrus/c:/jdk/eng/pulsar.html
-
-URL: file:///c:/jdk/eng/index.html
-spec: pulsar.html
-expected: file:/c:/jdk/eng/pulsar.html
-
-URL: file:///jdk/eng/index.html
-spec: pulsar.html
-expected: file:/jdk/eng/pulsar.html
-
-URL: file://JavaSoft/Test
-spec: file://radartoad.com/Test#bar
-expected: file://radartoad.com/Test#bar
-
-URL: file://JavaSoft/Test
-spec: /c:/Test#bar
-expected: file://JavaSoft/c:/Test#bar
\ No newline at end of file
--- a/test/java/net/URL/win32_file_urls	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-URL: null
-spec: file://c:\JavaSoft\Test
-expected: file://c:/JavaSoft/Test
-
-URL: null
-spec: file:/c:\JavaSoft\Test
-expected: file:/c:/JavaSoft/Test
-
-URL: null
-spec: file:/c:\JavaSoft\Test:something#anchor
-expected: file:/c:/JavaSoft/Test:something#anchor
-
-URL: file:///c:\jdk\eng\index.html
-spec: pulsar.html
-expected: file:/c:/jdk/eng/pulsar.html
\ No newline at end of file
--- a/test/java/net/URLConnection/RequestProperties.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/net/URLConnection/RequestProperties.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,90 +28,55 @@
  */
 
 import java.net.*;
+import java.util.ArrayList;
+import java.util.List;
 
 public class RequestProperties {
+    static int failed;
+
     public static void main (String args[]) throws Exception {
-        URL url0 = new URL ("http://foo.com/bar/");
-        URL url1 = new URL ("file:/etc/passwd");
-        URL url2 = new URL ("ftp://foo:bar@foobar.com/etc/passwd");
-        URL url3 = new URL ("jar:http://foo.com/bar.html!/foo/bar");
-        URLConnection urlc0 = url0.openConnection ();
-        URLConnection urlc1 = url1.openConnection ();
-        URLConnection urlc2 = url2.openConnection ();
-        URLConnection urlc3 = url3.openConnection ();
-        int count = 0;
-        String s = null;
+        List<String> urls = new ArrayList<>();
+        urls.add("http://foo.com/bar/");
+        urls.add("jar:http://foo.com/bar.html!/foo/bar");
+        urls.add("file:/etc/passwd");
+        if (hasFtp())
+            urls.add("ftp://foo:bar@foobar.com/etc/passwd");
+
+        for (String urlStr : urls)
+            test(new URL(urlStr));
+
+        if (failed != 0)
+            throw new RuntimeException(failed + " errors") ;
+    }
+
+    static void test(URL url) throws Exception {
+        URLConnection urlc = url.openConnection();
         try {
-            urlc0.setRequestProperty (null, null);
-            System.out.println ("http: setRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
+            urlc.setRequestProperty(null, null);
+            System.out.println(url.getProtocol()
+                               + ": setRequestProperty(null,) did not throw NPE");
+            failed++;
+        } catch (NullPointerException e) { /* Expected */ }
+        try {
+            urlc.addRequestProperty(null, null);
+            System.out.println(url.getProtocol()
+                               + ": addRequestProperty(null,) did not throw NPE");
+            failed++;
+        } catch (NullPointerException e)  { /* Expected */ }
+
+        if (urlc.getRequestProperty(null) != null) {
+            System.out.println(url.getProtocol()
+                               + ": getRequestProperty(null,) did not return null");
+            failed++;
         }
+    }
+
+    private static boolean hasFtp() {
         try {
-            urlc0.addRequestProperty (null, null);
-            System.out.println ("http: addRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
-        }
-        try {
-            urlc1.setRequestProperty (null, null);
-            System.out.println ("file: setRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
-        }
-        try {
-            urlc1.addRequestProperty (null, null);
-            System.out.println ("file: addRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
-        }
-        try {
-            urlc2.setRequestProperty (null, null);
-            System.out.println ("ftp: setRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
-        }
-        try {
-            urlc2.addRequestProperty (null, null);
-            System.out.println ("ftp: addRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
-        }
-        try {
-            urlc3.setRequestProperty (null, null);
-            System.out.println ("jar: setRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
-        }
-        try {
-            urlc3.addRequestProperty (null, null);
-            System.out.println ("jar: addRequestProperty (null,) did not throw NPE");
-        } catch (NullPointerException e) {
-            count ++;
-        }
-        if (urlc0.getRequestProperty (null) != null) {
-            System.out.println ("http: getRequestProperty (null,) did not return null");
-        } else {
-            count ++;
-        }
-        if (urlc1.getRequestProperty (null) != null) {
-            System.out.println ("file: getRequestProperty (null,) did not return null");
-        } else {
-            count ++;
-        }
-        if (urlc2.getRequestProperty (null) != null) {
-            System.out.println ("ftp: getRequestProperty (null,) did not return null");
-        } else {
-            count ++;
-        }
-        if (urlc2.getRequestProperty (null) != null) {
-            System.out.println ("jar: getRequestProperty (null,) did not return null");
-        } else {
-            count ++;
-        }
-
-        if (count != 12) {
-            throw new RuntimeException ((12 -count) + " errors") ;
+            return new java.net.URL("ftp://") != null;
+        } catch (java.net.MalformedURLException x) {
+            System.out.println("FTP not supported by this runtime.");
+            return false;
         }
     }
 }
--- a/test/java/net/URLConnection/RequestPropertyValues.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/net/URLConnection/RequestPropertyValues.java	Tue Feb 05 11:11:53 2013 -0800
@@ -27,8 +27,11 @@
  * @summary Test URLConnection Request Proterties
  */
 
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Part1:
@@ -45,28 +48,29 @@
     }
 
     public static void part1() throws Exception {
-        URL[] urls = { new URL("http://localhost:8088"),
-                        new URL("file:/etc/passwd"),
-                        new URL("ftp://foo:bar@foobar.com/etc/passwd"),
-                        new URL("jar:http://foo.com/bar.html!/foo/bar")
-                    };
+        List<URL> urls = new ArrayList<>();
+        urls.add(new URL("http://localhost:8088"));
+        urls.add(new URL("file:/etc/passwd"));
+        urls.add(new URL("jar:http://foo.com/bar.html!/foo/bar"));
+        if (hasFtp())
+            urls.add(new URL("ftp://foo:bar@foobar.com/etc/passwd"));
 
         boolean failed = false;
 
-        for (int proto = 0; proto < urls.length; proto++) {
-            URLConnection uc = (URLConnection) urls[proto].openConnection();
+        for (URL url : urls) {
+            URLConnection uc = url.openConnection();
             try {
                 uc.setRequestProperty("TestHeader", null);
             } catch (NullPointerException npe) {
                 System.out.println("setRequestProperty is throwing NPE" +
-                                " for url: " + urls[proto]);
+                                " for url: " + url);
                 failed = true;
             }
             try {
                 uc.addRequestProperty("TestHeader", null);
             } catch (NullPointerException npe) {
                 System.out.println("addRequestProperty is throwing NPE" +
-                                " for url: " + urls[proto]);
+                                " for url: " + url);
                 failed = true;
             }
         }
@@ -110,4 +114,12 @@
         }
     }
 
+    private static boolean hasFtp() {
+        try {
+            return new java.net.URL("ftp://") != null;
+        } catch (java.net.MalformedURLException x) {
+            System.out.println("FTP not supported by this runtime.");
+            return false;
+        }
+    }
 }
--- a/test/java/security/KeyStore/PBETest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/security/KeyStore/PBETest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -58,45 +58,46 @@
 
         new File(NEW_KEYSTORE).delete();
 
-        try {
-            KeyStore keystore = load(KEYSTORE_TYPE, KEYSTORE, PASSWORD);
-            KeyStore.Entry entry =
-                keystore.getEntry(ALIAS,
-                    new KeyStore.PasswordProtection(PASSWORD));
-            System.out.println("Retrieved entry named '" + ALIAS + "'");
+        KeyStore keystore = load(KEYSTORE_TYPE, KEYSTORE, PASSWORD);
+        KeyStore.Entry entry =
+            keystore.getEntry(ALIAS,
+                new KeyStore.PasswordProtection(PASSWORD));
+        System.out.println("Retrieved entry named '" + ALIAS + "'");
 
-            // Set entry
-            KeyStore keystore2 = load(NEW_KEYSTORE_TYPE, null, null);
-            keystore2.setEntry(ALIAS, entry,
-                new KeyStore.PasswordProtection(PASSWORD, PBE_ALGO,
-                    new PBEParameterSpec(SALT, ITERATION_COUNT,
-                        new IvParameterSpec(IV))));
-            System.out.println("Encrypted entry using: " + PBE_ALGO);
+        // Set entry
+        KeyStore keystore2 = load(NEW_KEYSTORE_TYPE, null, null);
+        keystore2.setEntry(ALIAS, entry,
+            new KeyStore.PasswordProtection(PASSWORD, PBE_ALGO,
+                new PBEParameterSpec(SALT, ITERATION_COUNT,
+                    new IvParameterSpec(IV))));
+        System.out.println("Encrypted entry using: " + PBE_ALGO);
 
+        try (FileOutputStream outStream = new FileOutputStream(NEW_KEYSTORE)) {
             System.out.println("Storing keystore to: " + NEW_KEYSTORE);
-            keystore2.store(new FileOutputStream(NEW_KEYSTORE), PASSWORD);
+            keystore2.store(outStream, PASSWORD);
+        }
 
-            keystore2 = load(NEW_KEYSTORE_TYPE, NEW_KEYSTORE, PASSWORD);
-            entry = keystore2.getEntry(ALIAS,
-                new KeyStore.PasswordProtection(PASSWORD));
-            System.out.println("Retrieved entry named '" + ALIAS + "'");
-
-        } finally {
-            new File(NEW_KEYSTORE).delete();
-            System.out.println("Deleted keystore: " + NEW_KEYSTORE);
-        }
+        keystore2 = load(NEW_KEYSTORE_TYPE, NEW_KEYSTORE, PASSWORD);
+        entry = keystore2.getEntry(ALIAS,
+            new KeyStore.PasswordProtection(PASSWORD));
+        System.out.println("Retrieved entry named '" + ALIAS + "'");
     }
 
     private static KeyStore load(String type, String path, char[] password)
         throws Exception {
+        KeyStore keystore = KeyStore.getInstance(type);
 
-        FileInputStream stream = null;
         if (path != null) {
-            stream = new FileInputStream(path);
+
+            try (FileInputStream inStream = new FileInputStream(path)) {
+                System.out.println("Loading keystore from: " + path);
+                keystore.load(inStream, password);
+                System.out.println("Loaded keystore with " + keystore.size() +
+                    " entries");
+            }
+        } else {
+            keystore.load(null, null);
         }
-        KeyStore keystore = KeyStore.getInstance(type);
-        System.out.println("Loading keystore from: " + path);
-        keystore.load(stream, password);
 
         return keystore;
     }
--- a/test/java/util/Base64/TestBase64.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/util/Base64/TestBase64.java	Tue Feb 05 11:11:53 2013 -0800
@@ -22,7 +22,7 @@
  */
 
 /**
- * @test 4235519 8004212
+ * @test 4235519 8004212 8005394 8007298 8006295 8006315 8006530
  * @summary tests java.util.Base64
  */
 
@@ -109,6 +109,15 @@
 
         // test return value from decode(ByteBuffer, ByteBuffer)
         testDecBufRet();
+
+        // test single-non-base64 character for mime decoding
+        testSingleNonBase64MimeDec();
+
+        // test decoding of unpadded data
+        testDecodeUnpadded();
+
+        // test mime decoding with ignored character after padding
+        testDecodeIgnoredAfterPadding();
     }
 
     private static sun.misc.BASE64Encoder sunmisc = new sun.misc.BASE64Encoder();
@@ -295,6 +304,7 @@
         checkNull(new Runnable() { public void run() { enc.encode(bb_null); }});
         checkNull(new Runnable() { public void run() { enc.encode(bb_null, ByteBuffer.allocate(10), 0); }});
         checkNull(new Runnable() { public void run() { enc.encode(ByteBuffer.allocate(10), bb_null, 0); }});
+        checkNull(new Runnable() { public void run() { enc.wrap(null); }});
     }
 
     private static void testNull(final Base64.Decoder dec) {
@@ -305,6 +315,7 @@
         checkNull(new Runnable() { public void run() { dec.decode(bb_null); }});
         checkNull(new Runnable() { public void run() { dec.decode(bb_null, ByteBuffer.allocate(10)); }});
         checkNull(new Runnable() { public void run() { dec.decode(ByteBuffer.allocate(10), bb_null); }});
+        checkNull(new Runnable() { public void run() { dec.wrap(null); }});
     }
 
     private static interface Testable {
@@ -354,6 +365,94 @@
         } catch (IllegalArgumentException iae) {}
     }
 
+    private static void testDecodeIgnoredAfterPadding() throws Throwable {
+        for (byte nonBase64 : new byte[] {'#', '(', '!', '\\', '-', '_', '\n', '\r'}) {
+            byte[][] src = new byte[][] {
+                "A".getBytes("ascii"),
+                "AB".getBytes("ascii"),
+                "ABC".getBytes("ascii"),
+                "ABCD".getBytes("ascii"),
+                "ABCDE".getBytes("ascii")
+            };
+            Base64.Encoder encM = Base64.getMimeEncoder();
+            Base64.Decoder decM = Base64.getMimeDecoder();
+            Base64.Encoder enc = Base64.getEncoder();
+            Base64.Decoder dec = Base64.getDecoder();
+            for (int i = 0; i < src.length; i++) {
+                // decode(byte[])
+                byte[] encoded = encM.encode(src[i]);
+                encoded = Arrays.copyOf(encoded, encoded.length + 1);
+                encoded[encoded.length - 1] = nonBase64;
+                checkEqual(decM.decode(encoded), src[i], "Non-base64 char is not ignored");
+                try {
+                    dec.decode(encoded);
+                    throw new RuntimeException("No IAE for non-base64 char");
+                } catch (IllegalArgumentException iae) {}
+
+                // decode(ByteBuffer[], ByteBuffer[])
+                ByteBuffer encodedBB = ByteBuffer.wrap(encoded);
+                ByteBuffer decodedBB = ByteBuffer.allocate(100);
+                int ret = decM.decode(encodedBB, decodedBB);
+                byte[] buf = new byte[ret];
+                decodedBB.flip();
+                decodedBB.get(buf);
+                checkEqual(buf, src[i], "Non-base64 char is not ignored");
+                try {
+                    encodedBB.rewind();
+                    decodedBB.clear();
+                    dec.decode(encodedBB, decodedBB);
+                    throw new RuntimeException("No IAE for non-base64 char");
+                } catch (IllegalArgumentException iae) {}
+                // direct
+                encodedBB.rewind();
+                decodedBB = ByteBuffer.allocateDirect(100);
+                ret = decM.decode(encodedBB, decodedBB);
+                buf = new byte[ret];
+                decodedBB.flip();
+                decodedBB.get(buf);
+                checkEqual(buf, src[i], "Non-base64 char is not ignored");
+                try {
+                    encodedBB.rewind();
+                    decodedBB.clear();
+                    dec.decode(encodedBB, decodedBB);
+                    throw new RuntimeException("No IAE for non-base64 char");
+                } catch (IllegalArgumentException iae) {}
+            }
+        }
+    }
+
+    private static void  testDecodeUnpadded() throws Throwable {
+        byte[] srcA = new byte[] { 'Q', 'Q' };
+        byte[] srcAA = new byte[] { 'Q', 'Q', 'E'};
+        Base64.Decoder dec = Base64.getDecoder();
+        byte[] ret = dec.decode(srcA);
+        if (ret[0] != 'A')
+            throw new RuntimeException("Decoding unpadding input A failed");
+        ret = dec.decode(srcAA);
+        if (ret[0] != 'A' && ret[1] != 'A')
+            throw new RuntimeException("Decoding unpadding input AA failed");
+        ret = new byte[10];
+        if (dec.wrap(new ByteArrayInputStream(srcA)).read(ret) != 1 &&
+            ret[0] != 'A')
+            throw new RuntimeException("Decoding unpadding input A from stream failed");
+        if (dec.wrap(new ByteArrayInputStream(srcA)).read(ret) != 2 &&
+            ret[0] != 'A' && ret[1] != 'A')
+            throw new RuntimeException("Decoding unpadding input AA from stream failed");
+    }
+
+    // single-non-base64-char should be ignored for mime decoding, but
+    // iae for basic decoding
+    private static void testSingleNonBase64MimeDec() throws Throwable {
+        for (String nonBase64 : new String[] {"#", "(", "!", "\\", "-", "_"}) {
+            if (Base64.getMimeDecoder().decode(nonBase64).length != 0) {
+                throw new RuntimeException("non-base64 char is not ignored");
+            }
+            try {
+                Base64.getDecoder().decode(nonBase64);
+                throw new RuntimeException("No IAE for single non-base64 char");
+            } catch (IllegalArgumentException iae) {}
+        }
+    }
 
     private static void testDecBufRet() throws Throwable {
         Random rnd = new java.util.Random();
--- a/test/java/util/Formatter/Basic-X.java.template	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/util/Formatter/Basic-X.java.template	Tue Feb 05 11:11:53 2013 -0800
@@ -1103,6 +1103,15 @@
         test("%.5f", "1.99999", val);
         test("%.6f", "1.999990", val);
 
+        val = new BigDecimal(0.9996);
+        test("%.0f", "1", val);
+        test("%.1f", "1.0", val);
+        test("%.2f", "1.00", val);
+        test("%.3f", "1.000", val);
+        test("%.4f", "0.9996", val);
+        test("%.5f", "0.99960", val);
+        test("%.6f", "0.999600", val);
+
 #end[BigDecimal]
 
 #if[float]
--- a/test/java/util/Formatter/BasicBigDecimal.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/java/util/Formatter/BasicBigDecimal.java	Tue Feb 05 11:11:53 2013 -0800
@@ -1103,6 +1103,15 @@
         test("%.5f", "1.99999", val);
         test("%.6f", "1.999990", val);
 
+        val = new BigDecimal(0.9996);
+        test("%.0f", "1", val);
+        test("%.1f", "1.0", val);
+        test("%.2f", "1.00", val);
+        test("%.3f", "1.000", val);
+        test("%.4f", "0.9996", val);
+        test("%.5f", "0.99960", val);
+        test("%.6f", "0.999600", val);
+
 
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/HashMap/HashMapCloneLeak.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,70 @@
+/*
+ * 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 7042126
+ * @summary Verify that we do not leak contents when we clone a HashMap
+ * @author david.buck@oracle.com
+ * @run main/othervm HashMapCloneLeak
+ * @run main/othervm -XX:+AggressiveOpts HashMapCloneLeak
+ */
+
+import java.util.HashMap;
+import java.lang.ref.WeakReference;
+
+public class HashMapCloneLeak {
+
+    static WeakReference<Object> wr = null;
+
+    // helper method to keep testObject and map out of main method's scope
+    private static HashMap<Integer, Object> makeMap() {
+        HashMap<Integer, Object> map = new HashMap<Integer, Object>();
+        Object testObject = new Object();
+        wr = new WeakReference<Object>(testObject);
+        map.put(42, testObject);
+        return map;
+    }
+
+    public static void main(String[] args) throws Exception {
+        HashMap<Integer, Object> hm = makeMap();
+        hm = (HashMap<Integer, Object>)hm.clone();
+        hm.clear();
+        // There should no longer be a strong reference to testObject
+        // the WeakReference should be nulled out by GC. If not,
+        // we will hang here until timed out by the test harness.
+        Object[] chain = null;
+        while (wr.get() != null) {
+            try {
+                Object[] allocate = new Object[1000000];
+                allocate[0] = chain;
+                chain = allocate;
+            } catch (OutOfMemoryError oome) {
+                chain = null;
+            }
+            System.gc();
+            Thread.sleep(100);
+        }
+    }
+
+}
--- a/test/javax/management/remote/mandatory/notif/DeadListenerTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/javax/management/remote/mandatory/notif/DeadListenerTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -31,6 +31,7 @@
 import com.sun.jmx.remote.internal.ServerNotifForwarder;
 import java.io.IOException;
 import java.lang.management.ManagementFactory;
+import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -86,20 +87,26 @@
         Map<ObjectName, Set<?>> listenerMap = (Map<ObjectName, Set<?>>) listenerMapF.get(serverNotifForwarder);
         assertTrue("Server listenerMap initially empty", mapWithoutKey(listenerMap, delegateName).isEmpty());
 
-        CountListener count1 = new CountListener();
+        final AtomicInteger count1Val = new AtomicInteger();
+        CountListener count1 = new CountListener(count1Val);
         mbsc.addNotificationListener(name, count1, null, null);
+        WeakReference<CountListener> count1Ref = new WeakReference<>(count1);
+        count1 = null;
 
-        CountListener count2 = new CountListener();
+        final AtomicInteger count2Val = new AtomicInteger();
+        CountListener count2 = new CountListener(count2Val);
         NotificationFilterSupport dummyFilter = new NotificationFilterSupport();
         dummyFilter.enableType("");
         mbsc.addNotificationListener(name, count2, dummyFilter, "noddy");
+        WeakReference<CountListener> count2Ref = new WeakReference<>(count2);
+        count2 = null;
 
         assertTrue("One entry in listenerMap for two listeners on same MBean", mapWithoutKey(listenerMap, delegateName).size() == 1);
         Set<?> set = listenerMap.get(name);
         assertTrue("Set in listenerMap for MBean has two elements", set != null && set.size() == 2);
 
-        assertTrue("Initial value of count1 == 0", count1.count() == 0);
-        assertTrue("Initial value of count2 == 0", count2.count() == 0);
+        assertTrue("Initial value of count1 == 0", count1Val.get() == 0);
+        assertTrue("Initial value of count2 == 0", count2Val.get() == 0);
 
         Notification notif = new Notification("type", name, 0);
 
@@ -107,11 +114,11 @@
 
         // Make sure notifs are working normally.
         long deadline = System.currentTimeMillis() + 2000;
-        while ((count1.count() != 1 || count2.count() != 1) && System.currentTimeMillis() < deadline) {
+        while ((count1Val.get() != 1 || count2Val.get() != 1) && System.currentTimeMillis() < deadline) {
             Thread.sleep(10);
         }
-        assertTrue("New value of count1 == 1", count1.count() == 1);
-        assertTrue("Initial value of count2 == 1", count2.count() == 1);
+        assertTrue("New value of count1 == 1", count1Val.get() == 1);
+        assertTrue("Initial value of count2 == 1", count2Val.get() == 1);
 
         // Make sure that removing a nonexistent listener from an existent MBean produces ListenerNotFoundException
         CountListener count3 = new CountListener();
@@ -136,28 +143,29 @@
         mbs.unregisterMBean(name);
         mbean.sendNotification(notif);
         Thread.sleep(200);
-        assertTrue("New value of count1 == 1", count1.count() == 1);
-        assertTrue("Initial value of count2 == 1", count2.count() == 1);
+
+        assertTrue("New value of count1 == 1", count1Val.get() == 1);
+        assertTrue("Initial value of count2 == 1", count2Val.get() == 1);
+
+        // wait for the listener cleanup to take place upon processing notifications
+        int countdown = 50; // waiting max. 5 secs
+        while (countdown-- > 0 &&
+                (count1Ref.get() != null ||
+                 count2Ref.get() != null)) {
+            System.gc();
+            Thread.sleep(100);
+            System.gc();
+        }
+        // listener has been removed or the wait has timed out
+
+        assertTrue("count1 notification listener has not been cleaned up", count1Ref.get() == null);
+        assertTrue("count2 notification listener has not been cleaned up", count2Ref.get() == null);
 
         // Check that there is no trace of the listeners any more in ServerNotifForwarder.listenerMap.
         // THIS DEPENDS ON JMX IMPLEMENTATION DETAILS.
         // If the JMX implementation changes, the code here may have to change too.
         Set<?> setForUnreg = listenerMap.get(name);
         assertTrue("No trace of unregistered MBean: " + setForUnreg, setForUnreg == null);
-
-        // Remove attempts should fail.
-        try {
-            mbsc.removeNotificationListener(name, count1);
-            assertTrue("Remove of count1 listener should have failed", false);
-        } catch (ListenerNotFoundException e) {
-            // OK: expected
-        }
-        try {
-            mbsc.removeNotificationListener(name, count2, dummyFilter, "noddy");
-            assertTrue("Remove of count2 listener should have failed", false);
-        } catch (ListenerNotFoundException e) {
-            // OK: expected
-        }
     }
 
     private static <K, V> Map<K, V> mapWithoutKey(Map<K, V> map, K key) {
@@ -173,6 +181,10 @@
     public static class CountListener implements NotificationListener {
         final AtomicInteger count;
 
+        public CountListener(AtomicInteger i) {
+            count = i;
+        }
+
         public CountListener() {
             this.count = new AtomicInteger();
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpClient.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.ProtocolFamily;
+import java.net.StandardProtocolFamily;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.util.Collections;
+import java.util.Enumeration;
+import sun.management.jdp.JdpException;
+import sun.management.jdp.JdpJmxPacket;
+
+public class JdpClient {
+
+    private static class PacketListener implements Runnable {
+
+        private static final int BUFFER_LENGTH = 4096;
+        private final DatagramChannel channel;
+        private static int maxPacketCount = 1;
+        private static int maxEmptyPacketCount = 10;
+
+
+        PacketListener(DatagramChannel channel) {
+            this.channel = channel;
+        }
+
+        @java.lang.Override
+        public void run() {
+            try {
+                Selector sel;
+                sel = Selector.open();
+                channel.configureBlocking(false);
+                channel.register(sel, SelectionKey.OP_READ);
+                ByteBuffer buf = ByteBuffer.allocate(1024);
+
+                int count = 1;
+                int emptyPacketsCount = 1;
+
+                try {
+                    while (true) {
+
+                        sel.selectedKeys().clear();
+                        buf.rewind();
+
+                        sel.select(10 * 1000);
+                        channel.receive(buf);
+
+                        if (buf.position() == 0 ){
+                            if (JdpDoSomething.getVerbose()){
+                                System.err.println("Empty packet received");
+                            }
+                            if (++emptyPacketsCount > maxEmptyPacketCount){
+                                throw new RuntimeException("Test failed, maxEmptyPacketCount reached");
+                            }
+
+                            continue;
+                        }
+
+                        buf.flip();
+                        byte[] dgramData = new byte[buf.remaining()];
+                        buf.get(dgramData);
+
+                        try {
+                            JdpJmxPacket packet = new JdpJmxPacket(dgramData);
+                            JdpDoSomething.printJdpPacket(packet);
+                            if(++count > maxPacketCount){
+                                   break;
+                            }
+                        } catch (JdpException e) {
+                            e.printStackTrace();
+                            throw new RuntimeException("Test failed");
+                        }
+
+                    }
+
+                    System.out.println("OK: Test passed");
+
+                } finally {
+                    sel.close();
+                    channel.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+                throw new RuntimeException("Test failed");
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        try {
+            String discoveryPort = System.getProperty("com.sun.management.jdp.port");
+            String discoveryAddress = System.getProperty("com.sun.management.jdp.address");
+            if (discoveryAddress == null || discoveryPort == null) {
+                System.out.println("Test failed. address and port must be specified");
+                return;
+            }
+
+            int port = Integer.parseInt(discoveryPort);
+            InetAddress address = InetAddress.getByName(discoveryAddress);
+
+
+            ProtocolFamily family = (address instanceof Inet6Address)
+                    ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
+
+            DatagramChannel channel;
+
+            channel = DatagramChannel.open(family);
+            channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
+            channel.bind(new InetSocketAddress(port));
+
+            Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
+            for (NetworkInterface interf : Collections.list(nets)) {
+                if (interf.supportsMulticast()) {
+                    try {
+                        channel.join(address, interf);
+                    } catch (IOException e) {
+                        // Skip not configured interfaces
+                    }
+                }
+            }
+
+            PacketListener listener = new PacketListener(channel);
+            new Thread(listener, "Jdp Client").start();
+
+        } catch (RuntimeException e){
+            System.out.println("Test failed.");
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("Test failed. unexpected error " + e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpDoSomething.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Objects;
+
+import sun.management.jdp.JdpJmxPacket;
+import sun.management.jdp.JdpException;
+
+public class JdpDoSomething {
+
+    private static final String lockFileName = "JdpDoSomething.lck";
+    private static final boolean verbose=false;
+
+    public static boolean getVerbose(){
+        return verbose;
+    }
+
+    public static void printJdpPacket(JdpJmxPacket p) {
+        if (getVerbose()) {
+            try {
+                RandomAccessFile f = new RandomAccessFile("out.dmp", "rw");
+                f.write(p.getPacketData());
+                f.close();
+            } catch (IOException e) {
+                System.out.println("Can't write a dump file: " + e);
+            }
+
+            System.out.println("Id: " + p.getId());
+            System.out.println("Jmx: " + p.getJmxServiceUrl());
+            System.out.println("Main: " + p.getMainClass());
+            System.out.println("InstanceName: " + p.getInstanceName());
+
+            System.out.flush();
+        }
+    }
+
+    public static void compaireJdpPacketEx(JdpJmxPacket p1, JdpJmxPacket p2)
+    throws JdpException {
+
+        if (!Objects.equals(p1, p1)) {
+            throw new JdpException("Packet mismatch error");
+        }
+
+        if (!Objects.equals(p1.getMainClass(), p2.getMainClass())) {
+            throw new JdpException("Packet mismatch error (main class)");
+        }
+
+        if (!Objects.equals(p1.getInstanceName(), p2.getInstanceName())) {
+            throw new JdpException("Packet mismatch error (instance name)");
+        }
+    }
+
+    public static void doSomething() {
+        try {
+            File lockFile = new File(lockFileName);
+            lockFile.createNewFile();
+
+            while (lockFile.exists()) {
+                long datetime = lockFile.lastModified();
+                long epoch = System.currentTimeMillis() / 1000;
+
+                // Don't allow test app to run more than an hour
+                if (epoch - datetime > 3600) {
+                    System.err.println("Lock is too old. Aborting");
+                    return;
+                }
+                Thread.sleep(1);
+            }
+
+        } catch (Throwable e) {
+            System.err.println("Something bad happens:" + e);
+        }
+    }
+
+    public static void main(String args[]) throws Exception {
+        System.err.println("main enter");
+        doSomething();
+        System.err.println("main exit");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpTest.sh	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,323 @@
+#!/bin/sh
+
+# Copyright (c) 2011, 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 7169888 
+# @build JdpUnitTest JdpClient JdpDoSomething 
+# @run shell JdpTest.sh --jtreg --no-compile
+# @summary No word Failed expected in the test output
+
+_verbose=no
+_jtreg=no
+_compile=yes
+
+# temporary disable jcmd related tests
+# _testsuite="01,02,03,04,05"
+_testsuite="01,02,04"
+
+_pwd=`pwd`
+
+_testclasses=".classes"
+_testsrc="${_pwd}"
+_lockFileName="JdpDoSomething.lck"
+
+_logname=".classes/output.txt"
+_last_pid=""
+
+
+_compile(){
+
+    if [ ! -e ${_testclasses} ]
+    then
+	  mkdir -p ${_testclasses}
+    fi   
+
+    rm -f ${_testclasses}/*.class
+
+    # Compile testcase
+    ${TESTJAVA}/bin/javac -d ${_testclasses} JdpUnitTest.java \
+                                             JdpDoSomething.java  \
+                                             JdpClient.java
+
+   
+    if [ ! -e ${_testclasses}/JdpDoSomething.class -o ! -e ${_testclasses}/JdpClient.class -o ! -e ${_testclasses}/JdpUnitTest.class ]
+    then
+      echo "ERROR: Can't compile"
+      exit -1
+    fi
+}
+
+
+_app_start(){
+
+  testappname=$1
+  shift
+
+  ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} ${testappname}  >> ${_logname} 2>&1 &
+ _last_pid=$!
+
+  npid=`_get_pid`
+  if [ "${npid}" = "" ]
+  then
+     echo "ERROR: Test app not started"
+     if [ "${_jtreg}" = "yes" ]
+     then
+       exit -1
+     fi
+  fi
+}
+
+_get_pid(){
+    ${TESTJAVA}/bin/jps | sed -n "/Jdp/s/ .*//p"
+}
+
+_app_stop(){
+   rm ${_lockFileName}
+
+# wait until VM is actually shuts down
+  while true 
+  do
+    npid=`_get_pid`
+    if [ "${npid}" = "" ] 
+    then
+      break
+    fi
+    sleep 1
+  done 
+}
+   
+_testme(){
+  ${TESTJAVA}/bin/java \
+  -cp ${_testclasses} \
+  $* \
+    -Dcom.sun.management.jdp.port=7095 \
+    -Dcom.sun.management.jdp.address=239.255.255.225 \
+  JdpClient 
+
+}   
+
+
+_jcmd(){
+    ${TESTJAVA}/bin/jcmd JdpDoSomething $* > /dev/null 2>/dev/null
+} 
+
+
+_echo(){
+    echo "$*"
+    echo "$*" >> ${_logname}
+}
+   
+# ============= TESTS ======================================
+   
+test_01(){
+		
+    _echo "**** Test one ****"		
+
+    _app_start JdpUnitTest \
+    -Dcom.sun.management.jdp.port=7095 \
+    -Dcom.sun.management.jdp.address=239.255.255.225 \
+    -Dcom.sun.management.jdp.pause=5
+
+    res=`_testme`
+
+    case "${res}" in 
+     OK*)  
+	_echo "Passed"
+     ;;
+     *)
+	_echo "Failed!"
+     ;;
+    esac
+
+    _app_stop
+}  
+
+test_02(){
+		
+    _echo "**** Test two ****"		
+
+    _app_start JdpDoSomething \
+     -Dcom.sun.management.jdp.port=7095 \
+     -Dcom.sun.management.jdp.address=239.255.255.225 \
+     -Dcom.sun.management.jdp.pause=5 \
+     -Dcom.sun.management.jmxremote.port=4545 \
+     -Dcom.sun.management.jmxremote.authenticate=false \
+     -Dcom.sun.management.jmxremote.ssl=false
+
+    res=`_testme`
+
+    case "${res}" in 
+     OK*)  
+	_echo "Passed"
+     ;;
+     *)
+	_echo "Failed!"
+     ;;
+    esac
+
+    _app_stop
+}  
+
+test_03(){
+		
+    _echo "**** Test three ****"
+
+    _app_start JdpDoSomething
+    
+    _jcmd  ManagementAgent.start\
+                jdp.port=7095 \
+                jdp.address=239.255.255.225 \
+                jdp.pause=5 \
+                jmxremote.port=4545 \
+                jmxremote.authenticate=false \
+                jmxremote.ssl=false
+
+    res=`_testme`
+
+    case "${res}" in 
+     OK*)  
+	_echo "Passed"
+     ;;
+     *)
+	_echo "Failed!"
+     ;;
+    esac
+
+    _app_stop
+}  
+
+test_04(){
+
+    _echo "**** Test four ****"
+
+    _app_start JdpDoSomething \
+     -Dcom.sun.management.jmxremote.autodiscovery=true \
+     -Dcom.sun.management.jmxremote.port=4545 \
+     -Dcom.sun.management.jmxremote.authenticate=false \
+     -Dcom.sun.management.jmxremote.ssl=false
+
+    res=`_testme`
+
+    case "${res}" in
+     OK*)
+	_echo "Passed"
+     ;;
+     *)
+	_echo "Failed!"
+     ;;
+    esac
+
+    _app_stop
+}
+
+test_05(){
+
+    _echo "**** Test five ****"
+
+    _app_start JdpDoSomething
+
+    _jcmd  ManagementAgent.start\
+                jmxremote.autodiscovery=true \
+                jmxremote.port=4545 \
+                jmxremote.authenticate=false \
+                jmxremote.ssl=false
+
+
+    res=`_testme`
+
+    case "${res}" in
+     OK*)
+	_echo "Passed"
+     ;;
+     *)
+	_echo "Failed!"
+     ;;
+    esac
+
+    _app_stop
+}
+
+
+# ============= MAIN =======================================
+
+if [ "x${TESTJAVA}" = "x" ]
+then
+  echo "TESTJAVA env have to be set"
+  exit
+fi
+
+#------------------------------------------------------------------------------
+# reading parameters 
+
+for parm in "$@"  
+do
+   case $parm in
+  --verbose)      _verbose=yes  ;;
+  --jtreg)        _jtreg=yes    ;;
+  --no-compile)   _compile=no   ;;
+  --testsuite=*)  _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"`  ;;
+  *) 
+     echo "Undefined parameter $parm. Try --help for help" 
+     exit 
+   ;;
+ esac 
+done
+
+if [ ${_compile} = "yes" ]
+then
+ _compile
+fi
+
+if [ ${_jtreg} = "yes" ]
+then
+ _testclasses=${TESTCLASSES}
+ _testsrc=${TESTSRC}
+ _logname="output.txt"
+fi
+
+# Make sure _tesclasses is absolute path
+tt=`echo ${_testclasses} | sed -e 's,/,,'`
+if [ ${tt} = ${_testclasses} ]
+then
+  _testclasses="${_pwd}/${_testclasses}"
+fi
+
+_policyname="${_testclasses}/policy"
+
+rm -f ${_logname}
+rm -f ${_policyname}
+
+if [ -e ${_testsrc}/policy.tpl ]
+then
+
+cat ${_testsrc}/policy.tpl | \
+     sed -e "s,@_TESTCLASSES@,${_testclasses},g" -e "s,@TESTJAVA@,${TESTJAVA},g" \
+ > ${_policyname}
+ 
+fi
+ 
+# Local mode tests
+for i in `echo ${_testsuite} | sed -e "s/,/ /g"`
+do
+  test_${i} 
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/management/jdp/JdpUnitTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.UUID;
+
+import sun.management.jdp.JdpController;
+import sun.management.jdp.JdpPacket;
+import sun.management.jdp.JdpJmxPacket;
+import sun.management.jdp.JdpException;
+
+public class JdpUnitTest {
+
+    /**
+     * This test tests that complete packet is build correctly
+     */
+    public static void PacketBuilderTest()
+        throws IOException, JdpException {
+
+        /* Complete packet test */
+        {
+            JdpJmxPacket p1 = new JdpJmxPacket(UUID.randomUUID(), "fake://unit-test");
+            p1.setMainClass("FakeUnitTest");
+            p1.setInstanceName("Fake");
+            byte[] b = p1.getPacketData();
+
+            JdpJmxPacket p2 = new JdpJmxPacket(b);
+            JdpDoSomething.printJdpPacket(p1);
+            JdpDoSomething.compaireJdpPacketEx(p1, p2);
+        }
+
+        /*Missed field packet test*/
+        {
+            JdpJmxPacket p1 = new JdpJmxPacket(UUID.randomUUID(), "fake://unit-test");
+            p1.setMainClass("FakeUnitTest");
+            p1.setInstanceName(null);
+            byte[] b = p1.getPacketData();
+
+            JdpJmxPacket p2 = new JdpJmxPacket(b);
+            JdpDoSomething.printJdpPacket(p1);
+            JdpDoSomething.compaireJdpPacketEx(p1, p2);
+        }
+
+         System.out.println("OK: Test passed");
+
+    }
+
+    public static void startFakeDiscoveryService()
+            throws IOException, JdpException {
+
+        String discoveryPort = System.getProperty("com.sun.management.jdp.port");
+        String discoveryAddress = System.getProperty("com.sun.management.jdp.address");
+        InetAddress address = InetAddress.getByName(discoveryAddress);
+        int port = Integer.parseInt(discoveryPort);
+        JdpController.startDiscoveryService(address, port, "FakeDiscovery", "fake://unit-test");
+    }
+
+    public static void main(String[] args) {
+        try {
+            PacketBuilderTest();
+            startFakeDiscoveryService();
+            JdpDoSomething.doSomething();
+
+        } catch (Throwable e) {
+            e.printStackTrace();
+            System.out.println("Test failed. unexpected error " + e);
+        }
+    }
+}
Binary file test/sun/net/ftp/EncDec.doc has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/ftp/MarkResetTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ *
+ * run from MarkResetTest.sh
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.regex.*;
+
+public class MarkResetTest {
+
+    /**
+     * A class that simulates, on a separate, an FTP server.
+     */
+    private class FtpServer extends Thread {
+        private ServerSocket    server;
+        private int port;
+        private boolean done = false;
+        private boolean pasvEnabled = true;
+        private boolean portEnabled = true;
+        private boolean extendedEnabled = true;
+
+        /**
+         * This Inner class will handle ONE client at a time.
+         * That's where 99% of the protocol handling is done.
+         */
+
+        private class FtpServerHandler extends Thread {
+            BufferedReader in;
+            PrintWriter out;
+            Socket client;
+            private final int ERROR = 0;
+            private final int USER = 1;
+            private final int PASS = 2;
+            private final int CWD =  3;
+            private final int TYPE = 4;
+            private final int RETR = 5;
+            private final int PASV = 6;
+            private final int PORT = 7;
+            private final int QUIT = 8;
+            private final int EPSV = 9;
+            String[] cmds = { "USER", "PASS", "CWD",
+                                "TYPE", "RETR", "PASV",
+                                "PORT", "QUIT", "EPSV"};
+            private String arg = null;
+            private ServerSocket pasv = null;
+            private int data_port = 0;
+            private InetAddress data_addr = null;
+
+            /**
+             * Parses a line to match it with one of the supported FTP commands.
+             * Returns the command number.
+             */
+
+            private int parseCmd(String cmd) {
+                if (cmd == null || cmd.length() < 3)
+                    return ERROR;
+                int blank = cmd.indexOf(' ');
+                if (blank < 0)
+                    blank = cmd.length();
+                if (blank < 3)
+                    return ERROR;
+                String s = cmd.substring(0, blank);
+                if (cmd.length() > blank+1)
+                    arg = cmd.substring(blank+1, cmd.length());
+                else
+                    arg = null;
+                for (int i = 0; i < cmds.length; i++) {
+                    if (s.equalsIgnoreCase(cmds[i]))
+                        return i+1;
+                }
+                return ERROR;
+            }
+
+            public FtpServerHandler(Socket cl) {
+                client = cl;
+            }
+
+            protected boolean isPasvSet() {
+                if (pasv != null && !pasvEnabled) {
+                    try {
+                        pasv.close();
+                    } catch (IOException ex) {
+                    }
+                    pasv = null;
+                }
+                if (pasvEnabled && pasv != null)
+                    return true;
+                return false;
+            }
+
+            /**
+             * Open the data socket with the client. This can be the
+             * result of a "PASV" or "PORT" command.
+             */
+
+            protected OutputStream getOutDataStream() {
+                try {
+                    if (isPasvSet()) {
+                        Socket s = pasv.accept();
+                        return s.getOutputStream();
+                    }
+                    if (data_addr != null) {
+                        Socket s = new Socket(data_addr, data_port);
+                        data_addr = null;
+                        data_port = 0;
+                        return s.getOutputStream();
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return null;
+            }
+
+            protected InputStream getInDataStream() {
+                try {
+                    if (isPasvSet()) {
+                        Socket s = pasv.accept();
+                        return s.getInputStream();
+                    }
+                    if (data_addr != null) {
+                        Socket s = new Socket(data_addr, data_port);
+                        data_addr = null;
+                        data_port = 0;
+                        return s.getInputStream();
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return null;
+            }
+
+            /**
+             * Handles the protocol exchange with the client.
+             */
+
+            public void run() {
+                boolean done = false;
+                String str;
+                int res;
+                boolean logged = false;
+                boolean waitpass = false;
+
+                try {
+                    in = new BufferedReader(new InputStreamReader(
+                                                client.getInputStream()));
+                    out = new PrintWriter(client.getOutputStream(), true);
+                    out.println("220 tatooine FTP server (SunOS 5.8) ready.");
+                } catch (Exception ex) {
+                    return;
+                }
+                while (!done) {
+                    try {
+                        str = in.readLine();
+                        res = parseCmd(str);
+                        if ((res > PASS && res != QUIT) && !logged) {
+                            out.println("530 Not logged in.");
+                            continue;
+                        }
+                        switch (res) {
+                        case ERROR:
+                            out.println("500 '" + str +
+                                        "': command not understood.");
+                            break;
+                        case USER:
+                            if (!logged && !waitpass) {
+                                out.println("331 Password required for " + arg);
+                                waitpass = true;
+                            } else {
+                                out.println("503 Bad sequence of commands.");
+                            }
+                            break;
+                        case PASS:
+                            if (!logged && waitpass) {
+                                out.println("230-Welcome to the FTP server!");
+                                out.println("ab");
+                                out.println("230 Guest login ok, " +
+                                            "access restrictions apply.");
+                                logged = true;
+                                waitpass = false;
+                            } else
+                                out.println("503 Bad sequence of commands.");
+                            break;
+                        case QUIT:
+                            out.println("221 Goodbye.");
+                            out.flush();
+                            out.close();
+                            if (pasv != null)
+                                pasv.close();
+                            done = true;
+                            break;
+                        case TYPE:
+                            out.println("200 Type set to " + arg + ".");
+                            break;
+                        case CWD:
+                            out.println("250 CWD command successful.");
+                            break;
+                        case EPSV:
+                            if (!extendedEnabled || !pasvEnabled) {
+                                out.println("500 EPSV is disabled, " +
+                                                "use PORT instead.");
+                                continue;
+                            }
+                            if ("all".equalsIgnoreCase(arg)) {
+                                out.println("200 EPSV ALL command successful.");
+                                continue;
+                            }
+                            try {
+                                if (pasv == null)
+                                    pasv = new ServerSocket(0);
+                                int port = pasv.getLocalPort();
+                                out.println("229 Entering Extended" +
+                                        " Passive Mode (|||" + port + "|)");
+                            } catch (IOException ssex) {
+                                out.println("425 Can't build data connection:" +
+                                                " Connection refused.");
+                            }
+                            break;
+
+                        case PASV:
+                            if (!pasvEnabled) {
+                                out.println("500 PASV is disabled, " +
+                                                "use PORT instead.");
+                                continue;
+                            }
+                            try {
+                                if (pasv == null)
+                                    pasv = new ServerSocket(0);
+                                int port = pasv.getLocalPort();
+
+                                // Parenthesis are optional, so let's be
+                                // nasty and don't put them
+                                out.println("227 Entering Passive Mode" +
+                                                " 127,0,0,1," +
+                                            (port >> 8) + "," + (port & 0xff));
+                            } catch (IOException ssex) {
+                                out.println("425 Can't build data connection:" +
+                                                 "Connection refused.");
+                            }
+                            break;
+                        case PORT:
+                            if (!portEnabled) {
+                                out.println("500 PORT is disabled, " +
+                                                "use PASV instead");
+                                continue;
+                            }
+                            StringBuffer host;
+                            int i = 0, j = 4;
+                            while (j > 0) {
+                                i = arg.indexOf(',', i + 1);
+                                if (i < 0)
+                                    break;
+                                j--;
+                            }
+                            if (j != 0) {
+                                out.println("500 '" + arg + "':" +
+                                            " command not understood.");
+                                continue;
+                            }
+                            try {
+                                host = new StringBuffer(arg.substring(0, i));
+                                for (j = 0; j < host.length(); j++)
+                                    if (host.charAt(j) == ',')
+                                        host.setCharAt(j, '.');
+                                String ports = arg.substring(i+1);
+                                i = ports.indexOf(',');
+                                data_port = Integer.parseInt(
+                                                ports.substring(0, i)) << 8;
+                                data_port += (Integer.parseInt(
+                                                ports.substring(i+1)));
+                                data_addr = InetAddress.getByName(
+                                                        host.toString());
+                                out.println("200 Command okay.");
+                            } catch (Exception ex3) {
+                                data_port = 0;
+                                data_addr = null;
+                                out.println("500 '" + arg + "':" +
+                                             " command not understood.");
+                            }
+                            break;
+                        case RETR:
+                            {
+                                File file = new File(arg);
+                                if (!file.exists()) {
+                                   System.out.println("File not found");
+                                   out.println("200 Command okay.");
+                                   out.println("550 '" + arg +
+                                            "' No such file or directory.");
+                                   break;
+                                }
+                                FileInputStream fin = new FileInputStream(file);
+                                OutputStream dout = getOutDataStream();
+                                if (dout != null) {
+                                   out.println("150 Binary data connection" +
+                                                " for " + arg +
+                                                " (" + client.getInetAddress().
+                                                getHostAddress() + ") (" +
+                                                file.length() + " bytes).");
+                                    int c;
+                                    int len = 0;
+                                    while ((c = fin.read()) != -1) {
+                                        dout.write(c);
+                                        len++;
+                                    }
+                                    dout.flush();
+                                    dout.close();
+                                    fin.close();
+                                   out.println("226 Binary Transfer complete.");
+                                } else {
+                                    out.println("425 Can't build data" +
+                                        " connection: Connection refused.");
+                                }
+                            }
+                            break;
+                        }
+                    } catch (IOException ioe) {
+                        ioe.printStackTrace();
+                        try {
+                            out.close();
+                        } catch (Exception ex2) {
+                        }
+                        done = true;
+                    }
+                }
+            }
+        }
+
+        public FtpServer(int port) {
+            this.port = port;
+        }
+
+        public FtpServer() {
+            this(21);
+        }
+
+        public int getPort() {
+            if (server != null)
+                return server.getLocalPort();
+            return 0;
+        }
+
+        /**
+         * A way to tell the server that it can stop.
+         */
+        synchronized public void terminate() {
+            done = true;
+        }
+
+
+        /*
+         * All we got to do here is create a ServerSocket and wait for a
+         * connection. When a connection happens, we just have to create
+         * a thread that will handle it.
+         */
+        public void run() {
+            try {
+                server = new ServerSocket(port);
+                Socket client;
+                client = server.accept();
+                (new FtpServerHandler(client)).start();
+                server.close();
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        MarkResetTest test = new MarkResetTest();
+    }
+
+    public MarkResetTest() {
+        FtpServer server = null;
+        try {
+            server = new FtpServer(0);
+            server.start();
+            int port = 0;
+            while (port == 0) {
+                Thread.sleep(500);
+                port = server.getPort();
+            }
+
+            String filename = "EncDec.doc";
+            URL url = new URL("ftp://localhost:" + port + "/" +
+                                filename);
+
+            URLConnection con = url.openConnection();
+            System.out.println("getContent: " + con.getContent());
+            System.out.println("getContent-length: " + con.getContentLength());
+
+            InputStream is = con.getInputStream();
+
+            /**
+             * guessContentTypeFromStream method calls mark and reset methods
+             * on the given stream. Make sure that calling
+             * guessContentTypeFromStream repeatedly does not affect
+             * reading from the stream afterwards
+             */
+            System.out.println("Call GuessContentTypeFromStream()" +
+                                " several times..");
+            for (int i = 0; i < 5; i++) {
+                System.out.println((i + 1) + " mime-type: " +
+                        con.guessContentTypeFromStream(is));
+            }
+
+            int len = 0;
+            int c;
+            while ((c = is.read()) != -1) {
+                len++;
+            }
+            is.close();
+            System.out.println("read: " + len + " bytes of the file");
+
+            // We're done!
+            server.terminate();
+            server.interrupt();
+
+            // Did we pass ?
+            if (len != (new File(filename)).length()) {
+                throw new Exception("Failed to read the file correctly");
+            }
+            System.out.println("PASSED: File read correctly");
+        } catch (Exception e) {
+            e.printStackTrace();
+            try {
+                server.terminate();
+                server.interrupt();
+            } catch (Exception ex) {
+            }
+            throw new RuntimeException("FTP support error: " + e.getMessage());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/net/ftp/MarkResetTest.sh	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,55 @@
+#
+# 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
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please 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 4673103
+# @run shell/timeout=140 MarkResetTest.sh
+# @summary URLConnection.getContent() hangs over FTP for DOC, PPT, XLS files
+
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    PS=":"
+    FS="/"
+    ;;
+  CYGWIN* )
+    PS=";"
+    FS="/"
+    ;;
+  Windows* )
+    PS=";"
+    FS="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}${FS}MarkResetTest.java
+
+# ftp server used by the test requires the file to be present
+# in this directory
+cp ${TESTSRC}${FS}EncDec.doc .
+
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} MarkResetTest
Binary file test/sun/net/www/EncDec.doc has changed
--- a/test/sun/net/www/MarkResetTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,455 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- *
- * run from MarkResetTest.sh
- */
-
-import java.io.*;
-import java.net.*;
-import java.util.regex.*;
-
-public class MarkResetTest {
-
-    /**
-     * A class that simulates, on a separate, an FTP server.
-     */
-    private class FtpServer extends Thread {
-        private ServerSocket    server;
-        private int port;
-        private boolean done = false;
-        private boolean pasvEnabled = true;
-        private boolean portEnabled = true;
-        private boolean extendedEnabled = true;
-
-        /**
-         * This Inner class will handle ONE client at a time.
-         * That's where 99% of the protocol handling is done.
-         */
-
-        private class FtpServerHandler extends Thread {
-            BufferedReader in;
-            PrintWriter out;
-            Socket client;
-            private final int ERROR = 0;
-            private final int USER = 1;
-            private final int PASS = 2;
-            private final int CWD =  3;
-            private final int TYPE = 4;
-            private final int RETR = 5;
-            private final int PASV = 6;
-            private final int PORT = 7;
-            private final int QUIT = 8;
-            private final int EPSV = 9;
-            String[] cmds = { "USER", "PASS", "CWD",
-                                "TYPE", "RETR", "PASV",
-                                "PORT", "QUIT", "EPSV"};
-            private String arg = null;
-            private ServerSocket pasv = null;
-            private int data_port = 0;
-            private InetAddress data_addr = null;
-
-            /**
-             * Parses a line to match it with one of the supported FTP commands.
-             * Returns the command number.
-             */
-
-            private int parseCmd(String cmd) {
-                if (cmd == null || cmd.length() < 3)
-                    return ERROR;
-                int blank = cmd.indexOf(' ');
-                if (blank < 0)
-                    blank = cmd.length();
-                if (blank < 3)
-                    return ERROR;
-                String s = cmd.substring(0, blank);
-                if (cmd.length() > blank+1)
-                    arg = cmd.substring(blank+1, cmd.length());
-                else
-                    arg = null;
-                for (int i = 0; i < cmds.length; i++) {
-                    if (s.equalsIgnoreCase(cmds[i]))
-                        return i+1;
-                }
-                return ERROR;
-            }
-
-            public FtpServerHandler(Socket cl) {
-                client = cl;
-            }
-
-            protected boolean isPasvSet() {
-                if (pasv != null && !pasvEnabled) {
-                    try {
-                        pasv.close();
-                    } catch (IOException ex) {
-                    }
-                    pasv = null;
-                }
-                if (pasvEnabled && pasv != null)
-                    return true;
-                return false;
-            }
-
-            /**
-             * Open the data socket with the client. This can be the
-             * result of a "PASV" or "PORT" command.
-             */
-
-            protected OutputStream getOutDataStream() {
-                try {
-                    if (isPasvSet()) {
-                        Socket s = pasv.accept();
-                        return s.getOutputStream();
-                    }
-                    if (data_addr != null) {
-                        Socket s = new Socket(data_addr, data_port);
-                        data_addr = null;
-                        data_port = 0;
-                        return s.getOutputStream();
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                return null;
-            }
-
-            protected InputStream getInDataStream() {
-                try {
-                    if (isPasvSet()) {
-                        Socket s = pasv.accept();
-                        return s.getInputStream();
-                    }
-                    if (data_addr != null) {
-                        Socket s = new Socket(data_addr, data_port);
-                        data_addr = null;
-                        data_port = 0;
-                        return s.getInputStream();
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                return null;
-            }
-
-            /**
-             * Handles the protocol exchange with the client.
-             */
-
-            public void run() {
-                boolean done = false;
-                String str;
-                int res;
-                boolean logged = false;
-                boolean waitpass = false;
-
-                try {
-                    in = new BufferedReader(new InputStreamReader(
-                                                client.getInputStream()));
-                    out = new PrintWriter(client.getOutputStream(), true);
-                    out.println("220 tatooine FTP server (SunOS 5.8) ready.");
-                } catch (Exception ex) {
-                    return;
-                }
-                while (!done) {
-                    try {
-                        str = in.readLine();
-                        res = parseCmd(str);
-                        if ((res > PASS && res != QUIT) && !logged) {
-                            out.println("530 Not logged in.");
-                            continue;
-                        }
-                        switch (res) {
-                        case ERROR:
-                            out.println("500 '" + str +
-                                        "': command not understood.");
-                            break;
-                        case USER:
-                            if (!logged && !waitpass) {
-                                out.println("331 Password required for " + arg);
-                                waitpass = true;
-                            } else {
-                                out.println("503 Bad sequence of commands.");
-                            }
-                            break;
-                        case PASS:
-                            if (!logged && waitpass) {
-                                out.println("230-Welcome to the FTP server!");
-                                out.println("ab");
-                                out.println("230 Guest login ok, " +
-                                            "access restrictions apply.");
-                                logged = true;
-                                waitpass = false;
-                            } else
-                                out.println("503 Bad sequence of commands.");
-                            break;
-                        case QUIT:
-                            out.println("221 Goodbye.");
-                            out.flush();
-                            out.close();
-                            if (pasv != null)
-                                pasv.close();
-                            done = true;
-                            break;
-                        case TYPE:
-                            out.println("200 Type set to " + arg + ".");
-                            break;
-                        case CWD:
-                            out.println("250 CWD command successful.");
-                            break;
-                        case EPSV:
-                            if (!extendedEnabled || !pasvEnabled) {
-                                out.println("500 EPSV is disabled, " +
-                                                "use PORT instead.");
-                                continue;
-                            }
-                            if ("all".equalsIgnoreCase(arg)) {
-                                out.println("200 EPSV ALL command successful.");
-                                continue;
-                            }
-                            try {
-                                if (pasv == null)
-                                    pasv = new ServerSocket(0);
-                                int port = pasv.getLocalPort();
-                                out.println("229 Entering Extended" +
-                                        " Passive Mode (|||" + port + "|)");
-                            } catch (IOException ssex) {
-                                out.println("425 Can't build data connection:" +
-                                                " Connection refused.");
-                            }
-                            break;
-
-                        case PASV:
-                            if (!pasvEnabled) {
-                                out.println("500 PASV is disabled, " +
-                                                "use PORT instead.");
-                                continue;
-                            }
-                            try {
-                                if (pasv == null)
-                                    pasv = new ServerSocket(0);
-                                int port = pasv.getLocalPort();
-
-                                // Parenthesis are optional, so let's be
-                                // nasty and don't put them
-                                out.println("227 Entering Passive Mode" +
-                                                " 127,0,0,1," +
-                                            (port >> 8) + "," + (port & 0xff));
-                            } catch (IOException ssex) {
-                                out.println("425 Can't build data connection:" +
-                                                 "Connection refused.");
-                            }
-                            break;
-                        case PORT:
-                            if (!portEnabled) {
-                                out.println("500 PORT is disabled, " +
-                                                "use PASV instead");
-                                continue;
-                            }
-                            StringBuffer host;
-                            int i = 0, j = 4;
-                            while (j > 0) {
-                                i = arg.indexOf(',', i + 1);
-                                if (i < 0)
-                                    break;
-                                j--;
-                            }
-                            if (j != 0) {
-                                out.println("500 '" + arg + "':" +
-                                            " command not understood.");
-                                continue;
-                            }
-                            try {
-                                host = new StringBuffer(arg.substring(0, i));
-                                for (j = 0; j < host.length(); j++)
-                                    if (host.charAt(j) == ',')
-                                        host.setCharAt(j, '.');
-                                String ports = arg.substring(i+1);
-                                i = ports.indexOf(',');
-                                data_port = Integer.parseInt(
-                                                ports.substring(0, i)) << 8;
-                                data_port += (Integer.parseInt(
-                                                ports.substring(i+1)));
-                                data_addr = InetAddress.getByName(
-                                                        host.toString());
-                                out.println("200 Command okay.");
-                            } catch (Exception ex3) {
-                                data_port = 0;
-                                data_addr = null;
-                                out.println("500 '" + arg + "':" +
-                                             " command not understood.");
-                            }
-                            break;
-                        case RETR:
-                            {
-                                File file = new File(arg);
-                                if (!file.exists()) {
-                                   System.out.println("File not found");
-                                   out.println("200 Command okay.");
-                                   out.println("550 '" + arg +
-                                            "' No such file or directory.");
-                                   break;
-                                }
-                                FileInputStream fin = new FileInputStream(file);
-                                OutputStream dout = getOutDataStream();
-                                if (dout != null) {
-                                   out.println("150 Binary data connection" +
-                                                " for " + arg +
-                                                " (" + client.getInetAddress().
-                                                getHostAddress() + ") (" +
-                                                file.length() + " bytes).");
-                                    int c;
-                                    int len = 0;
-                                    while ((c = fin.read()) != -1) {
-                                        dout.write(c);
-                                        len++;
-                                    }
-                                    dout.flush();
-                                    dout.close();
-                                    fin.close();
-                                   out.println("226 Binary Transfer complete.");
-                                } else {
-                                    out.println("425 Can't build data" +
-                                        " connection: Connection refused.");
-                                }
-                            }
-                            break;
-                        }
-                    } catch (IOException ioe) {
-                        ioe.printStackTrace();
-                        try {
-                            out.close();
-                        } catch (Exception ex2) {
-                        }
-                        done = true;
-                    }
-                }
-            }
-        }
-
-        public FtpServer(int port) {
-            this.port = port;
-        }
-
-        public FtpServer() {
-            this(21);
-        }
-
-        public int getPort() {
-            if (server != null)
-                return server.getLocalPort();
-            return 0;
-        }
-
-        /**
-         * A way to tell the server that it can stop.
-         */
-        synchronized public void terminate() {
-            done = true;
-        }
-
-
-        /*
-         * All we got to do here is create a ServerSocket and wait for a
-         * connection. When a connection happens, we just have to create
-         * a thread that will handle it.
-         */
-        public void run() {
-            try {
-                server = new ServerSocket(port);
-                Socket client;
-                client = server.accept();
-                (new FtpServerHandler(client)).start();
-                server.close();
-            } catch (Exception e) {
-            }
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        MarkResetTest test = new MarkResetTest();
-    }
-
-    public MarkResetTest() {
-        FtpServer server = null;
-        try {
-            server = new FtpServer(0);
-            server.start();
-            int port = 0;
-            while (port == 0) {
-                Thread.sleep(500);
-                port = server.getPort();
-            }
-
-            String filename = "EncDec.doc";
-            URL url = new URL("ftp://localhost:" + port + "/" +
-                                filename);
-
-            URLConnection con = url.openConnection();
-            System.out.println("getContent: " + con.getContent());
-            System.out.println("getContent-length: " + con.getContentLength());
-
-            InputStream is = con.getInputStream();
-
-            /**
-             * guessContentTypeFromStream method calls mark and reset methods
-             * on the given stream. Make sure that calling
-             * guessContentTypeFromStream repeatedly does not affect
-             * reading from the stream afterwards
-             */
-            System.out.println("Call GuessContentTypeFromStream()" +
-                                " several times..");
-            for (int i = 0; i < 5; i++) {
-                System.out.println((i + 1) + " mime-type: " +
-                        con.guessContentTypeFromStream(is));
-            }
-
-            int len = 0;
-            int c;
-            while ((c = is.read()) != -1) {
-                len++;
-            }
-            is.close();
-            System.out.println("read: " + len + " bytes of the file");
-
-            // We're done!
-            server.terminate();
-            server.interrupt();
-
-            // Did we pass ?
-            if (len != (new File(filename)).length()) {
-                throw new Exception("Failed to read the file correctly");
-            }
-            System.out.println("PASSED: File read correctly");
-        } catch (Exception e) {
-            e.printStackTrace();
-            try {
-                server.terminate();
-                server.interrupt();
-            } catch (Exception ex) {
-            }
-            throw new RuntimeException("FTP support error: " + e.getMessage());
-        }
-    }
-}
--- a/test/sun/net/www/MarkResetTest.sh	Tue Feb 05 11:10:07 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-#
-# 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
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please 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 4673103
-# @run shell/timeout=140 MarkResetTest.sh
-# @summary URLConnection.getContent() hangs over FTP for DOC, PPT, XLS files
-
-OS=`uname -s`
-case "$OS" in
-  SunOS | Linux | Darwin )
-    PS=":"
-    FS="/"
-    ;;
-  CYGWIN* )
-    PS=";"
-    FS="/"
-    ;;
-  Windows* )
-    PS=";"
-    FS="\\"
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . ${TESTSRC}${FS}MarkResetTest.java
-
-# ftp server used by the test requires the file to be present
-# in this directory
-cp ${TESTSRC}${FS}EncDec.doc .
-
-${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} MarkResetTest
--- a/test/sun/net/www/http/HttpClient/ProxyTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/sun/net/www/http/HttpClient/ProxyTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -161,8 +161,18 @@
         }
     }
 
+    private static boolean hasFtp() {
+        try {
+            return new java.net.URL("ftp://") != null;
+        } catch (java.net.MalformedURLException x) {
+            System.out.println("FTP not supported by this runtime.");
+            return false;
+        }
+    }
+
     public static void main(String[] args) throws Exception {
-        ProxyTest test = new ProxyTest();
+        if (hasFtp())
+           new ProxyTest();
     }
 
     public ProxyTest() throws Exception {
--- a/test/sun/security/pkcs12/StorePasswordTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/sun/security/pkcs12/StorePasswordTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -47,40 +47,49 @@
 
         new File(KEYSTORE).delete();
 
-        try {
+        KeyStore keystore = KeyStore.getInstance("PKCS12");
+        keystore.load(null, null);
 
-            KeyStore keystore = KeyStore.getInstance("PKCS12");
-            keystore.load(null, null);
+        // Set entry
+        Set<KeyStore.Entry.Attribute> attrs = new HashSet<>();
+        attrs.add(new PKCS12Attribute("1.3.5.7.9", "printable1"));
+        attrs.add(new PKCS12Attribute("2.4.6.8.10", "1F:2F:3F:4F:5F"));
+        int originalAttrCount = attrs.size() + 2;
+        keystore.setEntry(ALIAS,
+            new KeyStore.SecretKeyEntry(convertPassword(USER_PASSWORD), attrs),
+                new KeyStore.PasswordProtection(PASSWORD));
 
-            // Set entry
-            keystore.setEntry(ALIAS,
-                new KeyStore.SecretKeyEntry(convertPassword(USER_PASSWORD)),
-                    new KeyStore.PasswordProtection(PASSWORD));
+        try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) {
+            System.out.println("Storing keystore to: " + KEYSTORE);
+            keystore.store(outStream, PASSWORD);
+        }
 
-            System.out.println("Storing keystore to: " + KEYSTORE);
-            keystore.store(new FileOutputStream(KEYSTORE), PASSWORD);
-
+        try (FileInputStream inStream = new FileInputStream(KEYSTORE)) {
             System.out.println("Loading keystore from: " + KEYSTORE);
-            keystore.load(new FileInputStream(KEYSTORE), PASSWORD);
+            keystore.load(inStream, PASSWORD);
             System.out.println("Loaded keystore with " + keystore.size() +
                 " entries");
-            KeyStore.Entry entry = keystore.getEntry(ALIAS,
-                new KeyStore.PasswordProtection(PASSWORD));
-            System.out.println("Retrieved entry: " + entry);
+        }
 
-            SecretKey key = (SecretKey) keystore.getKey(ALIAS, PASSWORD);
-            SecretKeyFactory factory =
-                SecretKeyFactory.getInstance(key.getAlgorithm());
-            PBEKeySpec keySpec =
-                (PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class);
-            char[] pwd = keySpec.getPassword();
-            System.out.println("Recovered credential: " + new String(pwd));
+        KeyStore.Entry entry = keystore.getEntry(ALIAS,
+            new KeyStore.PasswordProtection(PASSWORD));
+        int attrCount = entry.getAttributes().size();
+        System.out.println("Retrieved entry with " + attrCount + " attrs: " +
+            entry);
+        if (attrCount != originalAttrCount) {
+            throw new Exception("Failed to recover all the entry attributes");
+        }
 
-            if (!Arrays.equals(USER_PASSWORD.toCharArray(), pwd)) {
-                throw new Exception("Failed to recover the stored password");
-            }
-        } finally {
-            new File(KEYSTORE).delete();
+        SecretKey key = (SecretKey) keystore.getKey(ALIAS, PASSWORD);
+        SecretKeyFactory factory =
+            SecretKeyFactory.getInstance(key.getAlgorithm());
+        PBEKeySpec keySpec =
+            (PBEKeySpec) factory.getKeySpec(key, PBEKeySpec.class);
+        char[] pwd = keySpec.getPassword();
+        System.out.println("Recovered credential: " + new String(pwd));
+
+        if (!Arrays.equals(USER_PASSWORD.toCharArray(), pwd)) {
+            throw new Exception("Failed to recover the stored password");
         }
     }
 
--- a/test/sun/security/pkcs12/StoreSecretKeyTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/sun/security/pkcs12/StoreSecretKeyTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -53,35 +53,34 @@
 
         new File(KEYSTORE).delete();
 
-        try {
+        KeyStore keystore = KeyStore.getInstance("PKCS12");
+        keystore.load(null, null);
 
-            KeyStore keystore = KeyStore.getInstance("PKCS12");
-            keystore.load(null, null);
+        // Set entry
+        keystore.setEntry(ALIAS,
+            new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)),
+                new KeyStore.PasswordProtection(PASSWORD));
 
-            // Set entry
-            keystore.setEntry(ALIAS,
-                new KeyStore.SecretKeyEntry(generateSecretKey("AES", 128)),
-                    new KeyStore.PasswordProtection(PASSWORD));
+        try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) {
+            System.out.println("Storing keystore to: " + KEYSTORE);
+            keystore.store(outStream, PASSWORD);
+        }
 
-            System.out.println("Storing keystore to: " + KEYSTORE);
-            keystore.store(new FileOutputStream(KEYSTORE), PASSWORD);
-
+        try (FileInputStream inStream = new FileInputStream(KEYSTORE)) {
             System.out.println("Loading keystore from: " + KEYSTORE);
-            keystore.load(new FileInputStream(KEYSTORE), PASSWORD);
+            keystore.load(inStream, PASSWORD);
             System.out.println("Loaded keystore with " + keystore.size() +
                 " entries");
-            KeyStore.Entry entry = keystore.getEntry(ALIAS,
-                new KeyStore.PasswordProtection(PASSWORD));
-            System.out.println("Retrieved entry: " + entry);
+        }
 
-            if (entry instanceof KeyStore.SecretKeyEntry) {
-                System.out.println("Retrieved secret key entry: " +
-                    entry);
-            } else {
-                throw new Exception("Not a secret key entry");
-            }
-        } finally {
-            new File(KEYSTORE).delete();
+        KeyStore.Entry entry = keystore.getEntry(ALIAS,
+            new KeyStore.PasswordProtection(PASSWORD));
+        System.out.println("Retrieved entry: " + entry);
+
+        if (entry instanceof KeyStore.SecretKeyEntry) {
+            System.out.println("Retrieved secret key entry: " + entry);
+        } else {
+            throw new Exception("Not a secret key entry");
         }
     }
 
--- a/test/sun/security/pkcs12/StoreTrustedCertTest.java	Tue Feb 05 11:10:07 2013 -0800
+++ b/test/sun/security/pkcs12/StoreTrustedCertTest.java	Tue Feb 05 11:11:53 2013 -0800
@@ -49,59 +49,57 @@
 
         new File(KEYSTORE).delete();
 
-        try {
-            KeyStore keystore = KeyStore.getInstance("PKCS12");
-            keystore.load(null, null);
+        KeyStore keystore = KeyStore.getInstance("PKCS12");
+        keystore.load(null, null);
 
-            Certificate cert = loadCertificate(CERT);
-            Set<KeyStore.Entry.Attribute> attributes = new HashSet<>();
-            attributes.add(new PKCS12Attribute("1.3.5.7.9", "that's odd"));
-            attributes.add(new PKCS12Attribute("2.4.6.8.10", "that's even"));
+        Certificate cert = loadCertificate(CERT);
+        Set<KeyStore.Entry.Attribute> attributes = new HashSet<>();
+        attributes.add(new PKCS12Attribute("1.3.5.7.9", "that's odd"));
+        attributes.add(new PKCS12Attribute("2.4.6.8.10", "that's even"));
 
-            // Set trusted certificate entry
-            keystore.setEntry(ALIAS,
-                new KeyStore.TrustedCertificateEntry(cert), null);
+        // Set trusted certificate entry
+        keystore.setEntry(ALIAS,
+            new KeyStore.TrustedCertificateEntry(cert), null);
 
-            // Set trusted certificate entry with attributes
-            keystore.setEntry(ALIAS2,
-                new KeyStore.TrustedCertificateEntry(cert, attributes), null);
+        // Set trusted certificate entry with attributes
+        keystore.setEntry(ALIAS2,
+            new KeyStore.TrustedCertificateEntry(cert, attributes), null);
 
+        try (FileOutputStream outStream = new FileOutputStream(KEYSTORE)) {
             System.out.println("Storing keystore to: " + KEYSTORE);
-            keystore.store(new FileOutputStream(KEYSTORE), PASSWORD);
+            keystore.store(outStream, PASSWORD);
+        }
 
+        try (FileInputStream inStream = new FileInputStream(KEYSTORE)) {
             System.out.println("Loading keystore from: " + KEYSTORE);
-            keystore.load(new FileInputStream(KEYSTORE), PASSWORD);
+            keystore.load(inStream, PASSWORD);
             System.out.println("Loaded keystore with " + keystore.size() +
                 " entries");
+        }
 
-            KeyStore.Entry entry = keystore.getEntry(ALIAS, null);
-            if (entry instanceof KeyStore.TrustedCertificateEntry) {
-                System.out.println("Retrieved trusted certificate entry: " +
-                    entry);
+        KeyStore.Entry entry = keystore.getEntry(ALIAS, null);
+        if (entry instanceof KeyStore.TrustedCertificateEntry) {
+            System.out.println("Retrieved trusted certificate entry: " + entry);
+        } else {
+            throw new Exception("Not a trusted certificate entry");
+        }
+        System.out.println();
+
+        entry = keystore.getEntry(ALIAS2, null);
+        if (entry instanceof KeyStore.TrustedCertificateEntry) {
+            KeyStore.TrustedCertificateEntry trustedEntry =
+                (KeyStore.TrustedCertificateEntry) entry;
+            Set<KeyStore.Entry.Attribute> entryAttributes =
+                trustedEntry.getAttributes();
+
+            if (entryAttributes.containsAll(attributes)) {
+                System.out.println("Retrieved trusted certificate entry " +
+                    "with attributes: " + entry);
             } else {
-                throw new Exception("Not a trusted certificate entry");
+                throw new Exception("Failed to retrieve entry attributes");
             }
-            System.out.println();
-
-            entry = keystore.getEntry(ALIAS2, null);
-            if (entry instanceof KeyStore.TrustedCertificateEntry) {
-                KeyStore.TrustedCertificateEntry trustedEntry =
-                    (KeyStore.TrustedCertificateEntry) entry;
-                Set<KeyStore.Entry.Attribute> entryAttributes =
-                    trustedEntry.getAttributes();
-
-                if (entryAttributes.containsAll(attributes)) {
-                    System.out.println("Retrieved trusted certificate entry " +
-                        "with attributes: " + entry);
-                } else {
-                    throw new Exception("Failed to retrieve entry attributes");
-                }
-            } else {
-                throw new Exception("Not a trusted certificate entry");
-            }
-
-        } finally {
-            new File(KEYSTORE).delete();
+        } else {
+            throw new Exception("Not a trusted certificate entry");
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/util/Oid/S11N.java	Tue Feb 05 11:11:53 2013 -0800
@@ -0,0 +1,246 @@
+/*
+ * 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 4811968 6908628 8006564
+ * @run main S11N check
+ * @summary Serialization compatibility with old versions (and fixes)
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import sun.misc.BASE64Encoder;
+import sun.security.util.ObjectIdentifier;
+
+public class S11N {
+    static String[] SMALL= {
+        "0.0",
+        "1.1",
+        "2.2",
+        "1.2.3456",
+        "1.2.2147483647.4",
+        "1.2.268435456.4",
+    };
+
+    static String[] HUGE = {
+        "2.16.764.1.3101555394.1.0.100.2.1",
+        "1.2.2147483648.4",
+        "2.3.4444444444444444444444",
+        "1.2.8888888888888888.33333333333333333.44444444444444",
+    };
+
+    // Do not use j.u.Base64, the test needs to run in jdk6
+    static BASE64Encoder encoder = new BASE64Encoder() {
+        @Override
+        protected int bytesPerLine() {
+            return 48;
+        }
+    };