changeset 350:b5ab848ba68f

Merge
author tbell
date Thu, 06 Aug 2009 19:03:42 -0700
parents ce9bcdcb7859 526de25e0b28
children 3e38c6da72ec
files
diffstat 49 files changed, 1661 insertions(+), 321 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Thu Aug 06 19:03:42 2009 -0700
@@ -76,6 +76,10 @@
         return (flags & mask) != 0;
     }
 
+    public int byteLength() {
+        return 2;
+    }
+
     private static final int[] classModifiers = {
         ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
     };
--- a/src/share/classes/com/sun/tools/classfile/Attribute.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/Attribute.java	Thu Aug 06 19:03:42 2009 -0700
@@ -166,6 +166,10 @@
 
     public abstract <R,D> R accept(Attribute.Visitor<R,D> visitor, D data);
 
+    public int byteLength() {
+        return 6 + attribute_length;
+    }
+
     public final int attribute_name_index;
     public final int attribute_length;
 
--- a/src/share/classes/com/sun/tools/classfile/Attributes.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/Attributes.java	Thu Aug 06 19:03:42 2009 -0700
@@ -95,6 +95,13 @@
         return attrs.length;
     }
 
+    public int byteLength() {
+        int length = 2;
+        for (Attribute a: attrs)
+            length += a.byteLength();
+        return length;
+    }
+
     public final Attribute[] attrs;
     public final Map<String, Attribute> map;
 }
--- a/src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java	Thu Aug 06 19:03:42 2009 -0700
@@ -58,7 +58,7 @@
     }
 
     public CharacterRangeTable_attribute(int name_index, Entry[] character_range_table) {
-        super(name_index, character_range_table.length * Entry.length());
+        super(name_index, 2 + character_range_table.length * Entry.length());
         this.character_range_table = character_range_table;
     }
 
--- a/src/share/classes/com/sun/tools/classfile/ClassFile.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ClassFile.java	Thu Aug 06 19:03:42 2009 -0700
@@ -139,6 +139,38 @@
         return access_flags.is(ACC_INTERFACE);
     }
 
+    public int byteLength() {
+        return  4 +     // magic
+                2 +     // minor
+                2 +     // major
+                constant_pool.byteLength() +
+                2 +     // access flags
+                2 +     // this_class
+                2 +     // super_class
+                byteLength(interfaces) +
+                byteLength(fields) +
+                byteLength(methods) +
+                attributes.byteLength();
+    }
+
+    private int byteLength(int[] indices) {
+        return 2 + 2 * indices.length;
+    }
+
+    private int byteLength(Field[] fields) {
+        int length = 2;
+        for (Field f: fields)
+            length += f.byteLength();
+        return length;
+    }
+
+    private int byteLength(Method[] methods) {
+        int length = 2;
+        for (Method m: methods)
+            length += m.byteLength();
+        return length;
+    }
+
     public final int magic;
     public final int minor_version;
     public final int major_version;
--- a/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Thu Aug 06 19:03:42 2009 -0700
@@ -25,7 +25,9 @@
 
 package com.sun.tools.classfile;
 
+import java.io.DataOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.Iterator;
 
 /**
@@ -179,6 +181,16 @@
         return pool.length;
     }
 
+    public int byteLength() {
+        int length = 2;
+        for (int i = 1; i < size(); ) {
+            CPInfo cpInfo = pool[i];
+            length += cpInfo.byteLength();
+            i += cpInfo.size();
+        }
+        return length;
+    }
+
     public CPInfo get(int index) throws InvalidIndex {
         if (index <= 0 || index >= pool.length)
             throw new InvalidIndex(index);
@@ -291,6 +303,8 @@
             return 1;
         }
 
+        public abstract int byteLength();
+
         public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
 
         protected final ConstantPool cp;
@@ -315,6 +329,10 @@
             return tag;
         }
 
+        public int byteLength() {
+            return 5;
+        }
+
         public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
             return cp.getClassInfo(class_index);
         }
@@ -347,6 +365,10 @@
             return CONSTANT_Class;
         }
 
+        public int  byteLength() {
+            return 3;
+        }
+
         public String getName() throws ConstantPoolException {
             return cp.getUTF8Value(name_index);
         }
@@ -390,6 +412,10 @@
             return CONSTANT_Double;
         }
 
+        public int  byteLength() {
+            return 9;
+        }
+
         @Override
         public int size() {
             return 2;
@@ -439,6 +465,10 @@
             return CONSTANT_Float;
         }
 
+        public int byteLength() {
+            return 5;
+        }
+
         @Override
         public String toString() {
             return "CONSTANT_Float_info[value: " + value + "]";
@@ -464,6 +494,10 @@
             return CONSTANT_Integer;
         }
 
+        public int byteLength() {
+            return 5;
+        }
+
         @Override
         public String toString() {
             return "CONSTANT_Integer_info[value: " + value + "]";
@@ -513,6 +547,10 @@
             return 2;
         }
 
+        public int byteLength() {
+            return 9;
+        }
+
         @Override
         public String toString() {
             return "CONSTANT_Long_info[value: " + value + "]";
@@ -561,6 +599,10 @@
             return CONSTANT_NameAndType;
         }
 
+        public int byteLength() {
+            return 5;
+        }
+
         public String getName() throws ConstantPoolException {
             return cp.getUTF8Value(name_index);
         }
@@ -597,6 +639,10 @@
             return CONSTANT_String;
         }
 
+        public int byteLength() {
+            return 3;
+        }
+
         public String getString() throws ConstantPoolException {
             return cp.getUTF8Value(string_index);
         }
@@ -626,6 +672,20 @@
             return CONSTANT_Utf8;
         }
 
+        public int byteLength() {
+            class SizeOutputStream extends OutputStream {
+                @Override
+                public void write(int b) throws IOException {
+                    size++;
+                }
+                int size;
+            }
+            SizeOutputStream sizeOut = new SizeOutputStream();
+            DataOutputStream out = new DataOutputStream(sizeOut);
+            try { out.writeUTF(value); } catch (IOException ignore) { }
+            return 1 + sizeOut.size;
+        }
+
         @Override
         public String toString() {
             if (value.length() < 32 && isPrintableAscii(value))
--- a/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ExtendedAnnotation.java	Thu Aug 06 19:03:42 2009 -0700
@@ -260,9 +260,6 @@
         // For generic/array types.
         public List<Integer> location = new ArrayList<Integer>();
 
-        // Tree position.
-        public int pos = -1;
-
         // For typecasts, type tests, new (and locals, as start_pc).
         public int offset = -1;
 
@@ -391,9 +388,6 @@
                 sb.append(")");
             }
 
-            sb.append(", pos = ");
-            sb.append(pos);
-
             sb.append(']');
             return sb.toString();
         }
--- a/src/share/classes/com/sun/tools/classfile/Field.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/Field.java	Thu Aug 06 19:03:42 2009 -0700
@@ -50,6 +50,10 @@
         this.attributes = attributes;
     }
 
+    public int byteLength() {
+        return 6 + attributes.byteLength();
+    }
+
     public String getName(ConstantPool constant_pool) throws ConstantPoolException {
         return constant_pool.getUTF8Value(name_index);
     }
--- a/src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java	Thu Aug 06 19:03:42 2009 -0700
@@ -50,7 +50,7 @@
     }
 
     public LineNumberTable_attribute(int name_index, Entry[] line_number_table) {
-        super(name_index, line_number_table.length * Entry.length());
+        super(name_index, 2 + line_number_table.length * Entry.length());
         this.line_number_table_length = line_number_table.length;
         this.line_number_table = line_number_table;
     }
--- a/src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java	Thu Aug 06 19:03:42 2009 -0700
@@ -50,7 +50,7 @@
     }
 
     public LocalVariableTable_attribute(int name_index, Entry[] local_variable_table) {
-        super(name_index, local_variable_table.length * Entry.length());
+        super(name_index, 2 + local_variable_table.length * Entry.length());
         this.local_variable_table_length = local_variable_table.length;
         this.local_variable_table = local_variable_table;
     }
--- a/src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java	Thu Aug 06 19:03:42 2009 -0700
@@ -50,7 +50,7 @@
     }
 
     public LocalVariableTypeTable_attribute(int name_index, Entry[] local_variable_table) {
-        super(name_index, local_variable_table.length * Entry.length());
+        super(name_index, 2 + local_variable_table.length * Entry.length());
         this.local_variable_table_length = local_variable_table.length;
         this.local_variable_table = local_variable_table;
     }
--- a/src/share/classes/com/sun/tools/classfile/Method.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/Method.java	Thu Aug 06 19:03:42 2009 -0700
@@ -50,6 +50,10 @@
         this.attributes = attributes;
     }
 
+    public int byteLength() {
+        return 6 + attributes.byteLength();
+    }
+
     public String getName(ConstantPool constant_pool) throws ConstantPoolException {
         return constant_pool.getUTF8Value(name_index);
     }
--- a/src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java	Thu Aug 06 19:03:42 2009 -0700
@@ -50,7 +50,7 @@
     }
 
     public ModuleExportTable_attribute(int name_index, int[] export_type_table) {
-        super(name_index, 2 * export_type_table.length);
+        super(name_index, 2 + 2 * export_type_table.length);
         this.export_type_table = export_type_table;
     }
 
--- a/src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java	Thu Aug 06 19:03:42 2009 -0700
@@ -49,7 +49,7 @@
     }
 
     public ModuleMemberTable_attribute(int name_index, int[] package_member_table) {
-        super(name_index, 2 * package_member_table.length);
+        super(name_index, 2 + 2 * package_member_table.length);
         this.package_member_table = package_member_table;
     }
 
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Aug 06 19:03:42 2009 -0700
@@ -1197,21 +1197,9 @@
          *  as possible implementations.
          */
         public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
-            for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
-                while (t.tag == TYPEVAR)
-                    t = t.getUpperBound();
-                TypeSymbol c = t.tsym;
-                for (Scope.Entry e = c.members().lookup(name);
-                     e.scope != null;
-                     e = e.next()) {
-                    if (e.sym.kind == MTH) {
-                        MethodSymbol m = (MethodSymbol) e.sym;
-                        if (m.overrides(this, origin, types, checkResult) &&
-                            (m.flags() & SYNTHETIC) == 0)
-                            return m;
-                    }
-                }
-            }
+            MethodSymbol res = types.implementation(this, origin, types, checkResult);
+            if (res != null)
+                return res;
             // if origin is derived from a raw type, we might have missed
             // an implementation because we do not know enough about instantiations.
             // in this case continue with the supertype as origin.
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Aug 06 19:03:42 2009 -0700
@@ -25,10 +25,9 @@
 
 package com.sun.tools.javac.code;
 
+import java.lang.ref.SoftReference;
 import java.util.*;
 
-import com.sun.tools.javac.api.Messages;
-
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.List;
 
@@ -1442,7 +1441,7 @@
         return (sym.flags() & STATIC) != 0
             ? sym.type
             : memberType.visit(t, sym);
-    }
+        }
     // where
         private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
 
@@ -1552,7 +1551,7 @@
             return t; /* fast special case */
         else
             return erasure.visit(t, recurse);
-    }
+        }
     // where
         private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
             public Type visitType(Type t, Boolean recurse) {
@@ -1946,6 +1945,45 @@
             hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
     }
 
+    private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_check =
+            new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>();
+
+    private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_nocheck =
+            new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>();
+
+    public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult) {
+        Map<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache = checkResult ?
+            implCache_check : implCache_nocheck;
+        SoftReference<Map<TypeSymbol, MethodSymbol>> ref_cache = implCache.get(ms);
+        Map<TypeSymbol, MethodSymbol> cache = ref_cache != null ? ref_cache.get() : null;
+        if (cache == null) {
+            cache = new HashMap<TypeSymbol, MethodSymbol>();
+            implCache.put(ms, new SoftReference<Map<TypeSymbol, MethodSymbol>>(cache));
+        }
+        MethodSymbol impl = cache.get(origin);
+        if (impl == null) {
+            for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
+                while (t.tag == TYPEVAR)
+                    t = t.getUpperBound();
+                TypeSymbol c = t.tsym;
+                for (Scope.Entry e = c.members().lookup(ms.name);
+                     e.scope != null;
+                     e = e.next()) {
+                    if (e.sym.kind == Kinds.MTH) {
+                        MethodSymbol m = (MethodSymbol) e.sym;
+                        if (m.overrides(ms, origin, types, checkResult) &&
+                            (m.flags() & SYNTHETIC) == 0) {
+                            impl = m;
+                            cache.put(origin, m);
+                            return impl;
+                        }
+                    }
+                }
+            }
+        }
+        return impl;
+    }
+
     /**
      * Does t have the same arguments as s?  It is assumed that both
      * types are (possibly polymorphic) method types.  Monomorphic
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -1040,15 +1040,6 @@
                     JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
                     try {
                         enterTypeAnnotations(annotations);
-
-                        // enrich type parameter symbols... easier for annotation processors
-                        if (tree instanceof JCTypeParameter) {
-                            JCTypeParameter typeparam = (JCTypeParameter)tree;
-                            ListBuffer<Attribute.Compound> buf = ListBuffer.lb();
-                            for (JCTypeAnnotation anno : annotations)
-                                buf.add(anno.attribute_field);
-                            typeparam.type.tsym.attributes_field = buf.toList();
-                        }
                     } finally {
                         log.useSource(prev);
                     }
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Aug 06 19:03:42 2009 -0700
@@ -817,6 +817,23 @@
             pop();
         }
 
+        private boolean inClass = false;
+
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+           if (!inClass) {
+               // Do not recurse into nested and inner classes since
+               // TransTypes.visitClassDef makes an invocation for each class
+               // separately.
+               inClass = true;
+               try {
+                   super.visitClassDef(tree);
+               } finally {
+                   inClass = false;
+               }
+           }
+        }
+
         private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame,
                 List<JCTree> path, TypeAnnotationPosition p) {
             switch (frame.getKind()) {
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Aug 06 19:03:42 2009 -0700
@@ -1003,7 +1003,7 @@
     inferred: {0}\n\
     bound(s): {1}
 compiler.misc.inferred.do.not.conform.to.params=\
-    actual arguments do not conforms to inferred formal arguments\n\
+    actual arguments do not conform to inferred formal arguments\n\
     required: {0}\n\
     found: {1}
 
--- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -208,6 +208,32 @@
         }
         return clauses.reverse();
     }
+
+    private int indexOf(Type type, WhereClauseKind kind) {
+        int index = 1;
+        for (Type t : whereClauses.get(kind).keySet()) {
+            if (t.tsym == type.tsym) {
+                return index;
+            }
+            if (kind != WhereClauseKind.TYPEVAR ||
+                    t.toString().equals(type.toString())) {
+                index++;
+            }
+        }
+        return -1;
+    }
+
+    private boolean unique(TypeVar typevar) {
+        int found = 0;
+        for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) {
+            if (t.toString().equals(typevar.toString())) {
+                found++;
+            }
+        }
+        if (found < 1)
+            throw new AssertionError("Missing type variable in where clause " + typevar);
+        return found == 1;
+    }
     //where
     /**
      * This enum defines all posssible kinds of where clauses that can be
@@ -366,33 +392,6 @@
             }
         }
 
-        private int indexOf(Type type, WhereClauseKind kind) {
-            int index = 0;
-            boolean found = false;
-            for (Type t : whereClauses.get(kind).keySet()) {
-                if (t == type) {
-                    found = true;
-                    break;
-                }
-                index++;
-            }
-            if (!found)
-                throw new AssertionError("Missing symbol in where clause " + type);
-            return index + 1;
-        }
-
-        private boolean unique(TypeVar typevar) {
-            int found = 0;
-            for (Type t : whereClauses.get(WhereClauseKind.TYPEVAR).keySet()) {
-                if (t.toString().equals(typevar.toString())) {
-                    found++;
-                }
-            }
-            if (found < 1)
-                throw new AssertionError("Missing type variable in where clause " + typevar);
-            return found == 1;
-        }
-
         @Override
         protected String printMethodArgs(List<Type> args, boolean varArgs, Locale locale) {
             return super.printMethodArgs(args, varArgs, locale);
@@ -492,7 +491,7 @@
 
         @Override
         public Void visitCapturedType(CapturedType t, Void ignored) {
-            if (!whereClauses.get(WhereClauseKind.CAPTURED).containsKey(t)) {
+            if (indexOf(t, WhereClauseKind.CAPTURED) == -1) {
                 String suffix = t.lower == syms.botType ? ".1" : "";
                 JCDiagnostic d = diags.fragment("where.captured"+ suffix, t, t.bound, t.lower, t.wildcard);
                 whereClauses.get(WhereClauseKind.CAPTURED).put(t, d);
@@ -506,7 +505,7 @@
         @Override
         public Void visitClassType(ClassType t, Void ignored) {
             if (t.isCompound()) {
-                if (!whereClauses.get(WhereClauseKind.INTERSECTION).containsKey(t)) {
+                if (indexOf(t, WhereClauseKind.INTERSECTION) == -1) {
                     Type supertype = types.supertype(t);
                     List<Type> interfaces = types.interfaces(t);
                     JCDiagnostic d = diags.fragment("where.intersection", t, interfaces.prepend(supertype));
@@ -524,11 +523,17 @@
 
         @Override
         public Void visitTypeVar(TypeVar t, Void ignored) {
-            if (!whereClauses.get(WhereClauseKind.TYPEVAR).containsKey(t)) {
+            if (indexOf(t, WhereClauseKind.TYPEVAR) == -1) {
+                //access the bound type and skip error types
                 Type bound = t.bound;
                 while ((bound instanceof ErrorType))
                     bound = ((ErrorType)bound).getOriginalType();
-                List<Type> bounds  = types.getBounds(t);
+                //retrieve the bound list - if the type variable
+                //has not been attributed the bound is not set
+                List<Type> bounds = bound != null ?
+                    types.getBounds(t) :
+                    List.<Type>nil();
+
                 nameSimplifier.addUsage(t.tsym);
 
                 boolean boundErroneous = bounds.head == null ||
--- a/src/share/classes/com/sun/tools/javap/AnnotationWriter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/AnnotationWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -32,6 +32,10 @@
 import com.sun.tools.classfile.Annotation.Class_element_value;
 import com.sun.tools.classfile.Annotation.Enum_element_value;
 import com.sun.tools.classfile.Annotation.Primitive_element_value;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
 
 /**
  *  A writer for writing annotations as text.
@@ -51,71 +55,243 @@
 
     protected AnnotationWriter(Context context) {
         super(context);
+        classWriter = ClassWriter.instance(context);
+        constantWriter = ConstantWriter.instance(context);
     }
 
     public void write(Annotation annot) {
-        print("#" + annot.type_index + "(");
+        write(annot, false);
+    }
+
+    public void write(Annotation annot, boolean resolveIndices) {
+        writeDescriptor(annot.type_index, resolveIndices);
+        boolean showParens = annot.num_element_value_pairs > 0 || !resolveIndices;
+        if (showParens)
+            print("(");
         for (int i = 0; i < annot.num_element_value_pairs; i++) {
             if (i > 0)
                 print(",");
-            write(annot.element_value_pairs[i]);
+            write(annot.element_value_pairs[i], resolveIndices);
         }
-        print(")");
+        if (showParens)
+            print(")");
     }
 
     public void write(ExtendedAnnotation annot) {
-        write(annot.annotation);
-        print('@');
-        print(annot.position.toString());
+        write(annot, true, false);
+    }
+
+    public void write(ExtendedAnnotation annot, boolean showOffsets, boolean resolveIndices) {
+        write(annot.annotation, resolveIndices);
+        print(": ");
+        write(annot.position, showOffsets);
+    }
+
+    public void write(ExtendedAnnotation.Position pos, boolean showOffsets) {
+        print(pos.type);
+
+        switch (pos.type) {
+        // type case
+        case TYPECAST:
+        case TYPECAST_GENERIC_OR_ARRAY:
+        // object creation
+        case INSTANCEOF:
+        case INSTANCEOF_GENERIC_OR_ARRAY:
+        // new expression
+        case NEW:
+        case NEW_GENERIC_OR_ARRAY:
+        case NEW_TYPE_ARGUMENT:
+        case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+            if (showOffsets) {
+                print(", offset=");
+                print(pos.offset);
+            }
+            break;
+         // local variable
+        case LOCAL_VARIABLE:
+        case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
+            print(", {");
+            for (int i = 0; i < pos.lvarOffset.length; ++i) {
+                if (i != 0) print("; ");
+                if (showOffsets) {
+                    print(", start_pc=");
+                    print(pos.lvarOffset[i]);
+                }
+                print(", length=");
+                print(pos.lvarLength[i]);
+                print(", index=");
+                print(pos.lvarIndex[i]);
+            }
+            print("}");
+            break;
+         // method receiver
+        case METHOD_RECEIVER:
+            // Do nothing
+            break;
+        // type parameters
+        case CLASS_TYPE_PARAMETER:
+        case METHOD_TYPE_PARAMETER:
+            print(", param_index=");
+            print(pos.parameter_index);
+            break;
+        // type parameters bound
+        case CLASS_TYPE_PARAMETER_BOUND:
+        case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+        case METHOD_TYPE_PARAMETER_BOUND:
+        case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+            print(", param_index=");
+            print(pos.parameter_index);
+            print(", bound_index=");
+            print(pos.bound_index);
+            break;
+         // wildcard
+        case WILDCARD_BOUND:
+        case WILDCARD_BOUND_GENERIC_OR_ARRAY:
+            print(", wild_card=");
+            print(pos.wildcard_position);
+            break;
+         // Class extends and implements clauses
+        case CLASS_EXTENDS:
+        case CLASS_EXTENDS_GENERIC_OR_ARRAY:
+            print(", type_index=");
+            print(pos.type_index);
+            break;
+        // throws
+        case THROWS:
+            print(", type_index=");
+            print(pos.type_index);
+            break;
+        case CLASS_LITERAL:
+            if (showOffsets) {
+                print(", offset=");
+                print(pos.offset);
+            }
+            break;
+        // method parameter: not specified
+        case METHOD_PARAMETER_GENERIC_OR_ARRAY:
+            print(", param_index=");
+            print(pos.parameter_index);
+            break;
+        // method type argument: wasn't specified
+        case METHOD_TYPE_ARGUMENT:
+        case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+            if (showOffsets) {
+                print(", offset=");
+                print(pos.offset);
+            }
+            print(", type_index=");
+            print(pos.type_index);
+            break;
+        // We don't need to worry abut these
+        case METHOD_RETURN_GENERIC_OR_ARRAY:
+        case FIELD_GENERIC_OR_ARRAY:
+            break;
+        case UNKNOWN:
+            break;
+        default:
+            throw new AssertionError("unknown type: " + pos.type);
+        }
+
+        // Append location data for generics/arrays.
+        if (pos.type.hasLocation()) {
+            print(", location=");
+            print(pos.location);
+        }
     }
 
     public void write(Annotation.element_value_pair pair) {
-        print("#" + pair.element_name_index + ":");
-        write(pair.value);
+        write(pair, false);
+    }
+
+    public void write(Annotation.element_value_pair pair, boolean resolveIndices) {
+        writeIndex(pair.element_name_index, resolveIndices);
+        print("=");
+        write(pair.value, resolveIndices);
     }
 
     public void write(Annotation.element_value value) {
-        ev_writer.write(value);
+        write(value, false);
+    }
+
+    public void write(Annotation.element_value value, boolean resolveIndices) {
+        ev_writer.write(value, resolveIndices);
+    }
+
+    private void writeDescriptor(int index, boolean resolveIndices) {
+        if (resolveIndices) {
+            try {
+                ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
+                Descriptor d = new Descriptor(index);
+                print(d.getFieldType(constant_pool));
+                return;
+            } catch (ConstantPoolException ignore) {
+            } catch (InvalidDescriptor ignore) {
+            }
+        }
+
+        print("#" + index);
+    }
+
+    private void writeIndex(int index, boolean resolveIndices) {
+        if (resolveIndices) {
+            print(constantWriter.stringValue(index));
+        } else
+            print("#" + index);
     }
 
     element_value_Writer ev_writer = new element_value_Writer();
 
-    class element_value_Writer implements Annotation.element_value.Visitor<Void,Void> {
-        public void write(Annotation.element_value value) {
-            value.accept(this, null);
+    class element_value_Writer implements Annotation.element_value.Visitor<Void,Boolean> {
+        public void write(Annotation.element_value value, boolean resolveIndices) {
+            value.accept(this, resolveIndices);
         }
 
-        public Void visitPrimitive(Primitive_element_value ev, Void p) {
-            print(((char) ev.tag) + "#" + ev.const_value_index);
+        public Void visitPrimitive(Primitive_element_value ev, Boolean resolveIndices) {
+            if (resolveIndices)
+                writeIndex(ev.const_value_index, resolveIndices);
+            else
+                print(((char) ev.tag) + "#" + ev.const_value_index);
             return null;
         }
 
-        public Void visitEnum(Enum_element_value ev, Void p) {
-            print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index);
+        public Void visitEnum(Enum_element_value ev, Boolean resolveIndices) {
+            if (resolveIndices) {
+                writeIndex(ev.type_name_index, resolveIndices);
+                print(".");
+                writeIndex(ev.const_name_index, resolveIndices);
+            } else
+                print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index);
             return null;
         }
 
-        public Void visitClass(Class_element_value ev, Void p) {
-            print(((char) ev.tag) + "#" + ev.class_info_index);
+        public Void visitClass(Class_element_value ev, Boolean resolveIndices) {
+            if (resolveIndices) {
+                writeIndex(ev.class_info_index, resolveIndices);
+                print(".class");
+            } else
+                print(((char) ev.tag) + "#" + ev.class_info_index);
             return null;
         }
 
-        public Void visitAnnotation(Annotation_element_value ev, Void p) {
+        public Void visitAnnotation(Annotation_element_value ev, Boolean resolveIndices) {
             print((char) ev.tag);
-            AnnotationWriter.this.write(ev.annotation_value);
+            AnnotationWriter.this.write(ev.annotation_value, resolveIndices);
             return null;
         }
 
-        public Void visitArray(Array_element_value ev, Void p) {
+        public Void visitArray(Array_element_value ev, Boolean resolveIndices) {
             print("[");
             for (int i = 0; i < ev.num_values; i++) {
                 if (i > 0)
                     print(",");
-                write(ev.values[i]);
+                write(ev.values[i], resolveIndices);
             }
             print("]");
             return null;
         }
 
     }
+
+    private ClassWriter classWriter;
+    private ConstantWriter constantWriter;
 }
--- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -41,7 +41,6 @@
 import com.sun.tools.classfile.Deprecated_attribute;
 import com.sun.tools.classfile.EnclosingMethod_attribute;
 import com.sun.tools.classfile.Exceptions_attribute;
-import com.sun.tools.classfile.Field;
 import com.sun.tools.classfile.InnerClasses_attribute;
 import com.sun.tools.classfile.LineNumberTable_attribute;
 import com.sun.tools.classfile.LocalVariableTable_attribute;
@@ -149,22 +148,26 @@
     }
 
     public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) {
-        println("  AnnotationDefault: ");
-        print("    default_value: ");
+        println("AnnotationDefault:");
+        indent(+1);
+        print("default_value: ");
         annotationWriter.write(attr.default_value);
+        indent(-1);
         return null;
     }
 
     public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
-        print("  CharacterRangeTable: ");
+        println("CharacterRangeTable:");
+        indent(+1);
         for (int i = 0; i < attr.character_range_table.length; i++) {
             CharacterRangeTable_attribute.Entry e = attr.character_range_table[i];
             print("    " + e.start_pc + ", " +
                     e.end_pc + ", " +
                     Integer.toHexString(e.character_range_start) + ", " +
                     Integer.toHexString(e.character_range_end) + ", " +
-                    Integer.toHexString(e.flags) +
-                    "\t// ");
+                    Integer.toHexString(e.flags));
+            tab();
+            print("// ");
             print(e.start_pc + ", " +
                     e.end_pc + ", " +
                     (e.character_range_start >> 10) + ":" + (e.character_range_start & 0x3ff) + ", " +
@@ -187,16 +190,13 @@
                 print(", branch-true");
             if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0)
                 print(", branch-false");
-
-
-
         }
+        indent(-1);
         return null;
     }
 
     public Void visitCode(Code_attribute attr, Void ignore) {
         codeWriter.write(attr, constant_pool);
-        println();
         return null;
     }
 
@@ -207,25 +207,23 @@
 
     public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) {
         if (options.compat) // BUG 6622216 javap names some attributes incorrectly
-            print("  Constant value: ");
+            print("Constant value: ");
         else
-            print("  ConstantValue: ");
+            print("ConstantValue: ");
         constantWriter.write(attr.constantvalue_index);
-        if (!options.compat) // BUG 6622232 javap gets whitespace confused
-            println();
+        println();
         return null;
     }
 
     public Void visitDeprecated(Deprecated_attribute attr, Void ignore) {
-        if (!(options.compat && owner instanceof Field)) // BUG 6622232 javap gets whitespace confused
-            print("  ");
         println("Deprecated: true");
         return null;
     }
 
     public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) {
-        print("  EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index
-                + "\t// " + getJavaClassName(attr));
+        print("EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index);
+        tab();
+        print("// " + getJavaClassName(attr));
         if (attr.method_index != 0)
             print("." + getMethodName(attr));
         println();
@@ -249,15 +247,16 @@
     }
 
     public Void visitExceptions(Exceptions_attribute attr, Void ignore) {
-        println("  Exceptions: ");
-        print("   throws ");
+        println("Exceptions:");
+        indent(+1);
+        print("throws ");
         for (int i = 0; i < attr.number_of_exceptions; i++) {
             if (i > 0)
                 print(", ");
             print(getJavaException(attr, i));
         }
-        if (!options.compat) // BUG 6622232 javap gets whitespace confused
-            println();
+        println();
+        indent(-1);
         return null;
     }
 
@@ -290,8 +289,7 @@
                     writeInnerClassHeader();
                     first = false;
                 }
-                if (!options.compat) // BUG 6622232: javap gets whitespace confused
-                    print("   ");
+                print("   ");
                 for (String name: access_flags.getInnerClassModifiers())
                     print(name + " ");
                 if (info.inner_name_index!=0) {
@@ -313,6 +311,8 @@
                 println();
             }
         }
+        if (!first)
+            indent(-1);
         return null;
     }
 
@@ -325,26 +325,28 @@
     }
 
     private void writeInnerClassHeader() {
-        print("  ");
         if (options.compat) // BUG 6622216: javap names some attributes incorrectly
             print("InnerClass");
         else
             print("InnerClasses");
-        println(": ");
+        println(":");
+        indent(+1);
     }
 
     public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) {
-        println("  LineNumberTable: ");
+        println("LineNumberTable:");
+        indent(+1);
         for (LineNumberTable_attribute.Entry entry: attr.line_number_table) {
-            println("   line " + entry.line_number + ": " + entry.start_pc);
+            println("line " + entry.line_number + ": " + entry.start_pc);
         }
+        indent(-1);
         return null;
     }
 
     public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) {
-        println("  LocalVariableTable: ");
-        println("   Start  Length  Slot  Name   Signature");
-
+        println("LocalVariableTable:");
+        indent(+1);
+        println("Start  Length  Slot  Name   Signature");
         for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) {
             Formatter formatter = new Formatter();
             println(formatter.format("%8d %7d %5d %5s   %s",
@@ -352,25 +354,28 @@
                     constantWriter.stringValue(entry.name_index),
                     constantWriter.stringValue(entry.descriptor_index)));
         }
+        indent(-1);
         return null;
     }
 
     public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) {
-        println("  LocalVariableTypeTable: ");
-        println("   Start  Length  Slot  Name   Signature");
-
+        println("LocalVariableTypeTable:");
+        indent(+1);
+        println("Start  Length  Slot  Name   Signature");
         for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) {
-            Formatter formatter = new Formatter();
-            println(formatter.format("%8d %7d %5d %5s   %s",
+            println(String.format("%5d %7d %5d %5s   %s",
                     entry.start_pc, entry.length, entry.index,
                     constantWriter.stringValue(entry.name_index),
                     constantWriter.stringValue(entry.signature_index)));
         }
+        indent(-1);
         return null;
     }
 
     public Void visitModule(Module_attribute attr, Void ignore) {
-        println("  Module: #" + attr.module_name + "\t// " + getModuleName(attr));
+        print("Module: #" + attr.module_name);
+        tab();
+        println("// " + getModuleName(attr));
         return null;
     }
 
@@ -383,11 +388,15 @@
     }
 
     public Void visitModuleExportTable(ModuleExportTable_attribute attr, Void ignore) {
-        println("  ModuleExportTable:");
-        println("    Types: (" + attr.export_type_table.length + ")");
+        println("ModuleExportTable:");
+        indent(+1);
+        println("Types: (" + attr.export_type_table.length + ")");
         for (int i = 0; i < attr.export_type_table.length; i++) {
-            println("      #" + attr.export_type_table[i] + "\t// " + getExportTypeName(attr, i));
+            print("#" + attr.export_type_table[i]);
+            tab();
+            println("// " + getExportTypeName(attr, i));
         }
+        indent(-1);
         return null;
     }
 
@@ -400,11 +409,15 @@
     }
 
     public Void visitModuleMemberTable(ModuleMemberTable_attribute attr, Void ignore) {
-        println("  ModuleMemberTable:");
-        println("    Packages: (" + attr.package_member_table.length + ")");
+        println("ModuleMemberTable:");
+        indent(+1);
+        println("Packages: (" + attr.package_member_table.length + ")");
         for (int i = 0; i < attr.package_member_table.length; i++) {
-            println("      #" + attr.package_member_table[i] + "\t// " + getPackageMemberName(attr, i));
+            print("#" + attr.package_member_table[i]);
+            tab();
+            println("// " + getPackageMemberName(attr, i));
         }
+        indent(-1);
         return null;
     }
 
@@ -417,73 +430,91 @@
     }
 
     public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
-        println("  RuntimeVisibleAnnotations: ");
+        println("RuntimeVisibleAnnotations:");
+        indent(+1);
         for (int i = 0; i < attr.annotations.length; i++) {
-            print("    " + i + ": ");
+            print(i + ": ");
             annotationWriter.write(attr.annotations[i]);
             println();
         }
+        indent(-1);
         return null;
     }
 
     public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) {
-        println("  RuntimeInvisibleAnnotations: ");
+        println("RuntimeInvisibleAnnotations:");
+        indent(+1);
         for (int i = 0; i < attr.annotations.length; i++) {
-            print("    " + i + ": ");
+            print(i + ": ");
             annotationWriter.write(attr.annotations[i]);
             println();
         }
+        indent(-1);
         return null;
     }
 
     public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) {
-        println("  RuntimeVisibleTypeAnnotations: ");
+        println("RuntimeVisibleTypeAnnotations:");
+        indent(+1);
         for (int i = 0; i < attr.annotations.length; i++) {
-            print("    " + i + ": ");
+            print(i + ": ");
             annotationWriter.write(attr.annotations[i]);
             println();
         }
+        indent(-1);
         return null;
     }
 
     public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) {
-        println("  RuntimeInvisibleTypeAnnotations: ");
+        println("RuntimeInvisibleTypeAnnotations:");
+        indent(+1);
         for (int i = 0; i < attr.annotations.length; i++) {
-            print("    " + i + ": ");
+            print(i + ": ");
             annotationWriter.write(attr.annotations[i]);
             println();
         }
+        indent(-1);
         return null;
     }
 
     public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
-        println("  RuntimeVisibleParameterAnnotations: ");
+        println("RuntimeVisibleParameterAnnotations:");
+        indent(+1);
         for (int param = 0; param < attr.parameter_annotations.length; param++) {
-            println("    parameter " + param + ": ");
+            println("parameter " + param + ": ");
+            indent(+1);
             for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
-                print("    " + i + ": ");
+                print(i + ": ");
                 annotationWriter.write(attr.parameter_annotations[param][i]);
                 println();
             }
+            indent(-1);
         }
+        indent(-1);
         return null;
     }
 
     public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) {
-        println("  RuntimeInvisibleParameterAnnotations: ");
+        println("RuntimeInvisibleParameterAnnotations:");
+        indent(+1);
         for (int param = 0; param < attr.parameter_annotations.length; param++) {
-            println("    " + param + ": ");
+            println(param + ": ");
+            indent(+1);
             for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
-                print("    " + i + ": ");
+                print(i + ": ");
                 annotationWriter.write(attr.parameter_annotations[param][i]);
                 println();
             }
+            indent(-1);
         }
+        indent(-1);
         return null;
     }
 
     public Void visitSignature(Signature_attribute attr, Void ignore) {
-        println("  Signature: #" + attr.signature_index + "\t// " + getSignature(attr));
+        print("Signature: #" + attr.signature_index);
+        tab();
+        println("// " + getSignature(attr));
         return null;
     }
 
@@ -496,12 +527,12 @@
     }
 
     public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) {
-        println("  SourceDebugExtension: " + attr.getValue());
+        println("SourceDebugExtension: " + attr.getValue());
         return null;
     }
 
     public Void visitSourceFile(SourceFile_attribute attr, Void ignore) {
-        println("  SourceFile: \"" + getSourceFile(attr) + "\"");
+        println("SourceFile: \"" + getSourceFile(attr) + "\"");
         return null;
     }
 
@@ -519,24 +550,26 @@
     }
 
     public Void visitStackMap(StackMap_attribute attr, Void ignore) {
-        println("  StackMap: number_of_entries = " + attr.number_of_entries);
-
+        println("StackMap: number_of_entries = " + attr.number_of_entries);
+        indent(+1);
         StackMapTableWriter w = new StackMapTableWriter();
         for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
             w.write(entry);
         }
         println();
+        indent(-1);
         return null;
     }
 
     public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) {
-        println("  StackMapTable: number_of_entries = " + attr.number_of_entries);
-
+        println("StackMapTable: number_of_entries = " + attr.number_of_entries);
+        indent(+1);
         StackMapTableWriter w = new StackMapTableWriter();
         for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
             w.write(entry);
         }
         println();
+        indent(-1);
         return null;
     }
 
@@ -555,29 +588,37 @@
         public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) {
             printHeader(frame);
             println(" /* same_locals_1_stack_item */");
+            indent(+1);
             printMap("stack", frame.stack);
+            indent(-1);
             return null;
         }
 
         public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) {
             printHeader(frame);
             println(" /* same_locals_1_stack_item_frame_extended */");
-            println("     offset_delta = " + frame.offset_delta);
+            indent(+1);
+            println("offset_delta = " + frame.offset_delta);
             printMap("stack", frame.stack);
+            indent(-1);
             return null;
         }
 
         public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) {
             printHeader(frame);
             println(" /* chop */");
-            println("     offset_delta = " + frame.offset_delta);
+            indent(+1);
+            println("offset_delta = " + frame.offset_delta);
+            indent(-1);
             return null;
         }
 
         public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) {
             printHeader(frame);
             println(" /* same_frame_extended */");
-            println("     offset_delta = " + frame.offset_delta);
+            indent(+1);
+            println("offset_delta = " + frame.offset_delta);
+            indent(-1);
             return null;
         }
 
@@ -592,13 +633,16 @@
         public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) {
             printHeader(frame);
             if (frame instanceof StackMap_attribute.stack_map_frame) {
-                println("     offset = " + frame.offset_delta);
+                indent(+1);
+                println(" offset = " + frame.offset_delta);
             } else {
                 println(" /* full_frame */");
-                println("     offset_delta = " + frame.offset_delta);
+                indent(+1);
+                println("offset_delta = " + frame.offset_delta);
             }
             printMap("locals", frame.locals);
             printMap("stack", frame.stack);
+            indent(-1);
             return null;
         }
 
@@ -607,7 +651,7 @@
         }
 
         void printMap(String name, StackMapTable_attribute.verification_type_info[] map) {
-            print("     " + name + " = [");
+            print(name + " = [");
             for (int i = 0; i < map.length; i++) {
                 StackMapTable_attribute.verification_type_info info = map[i];
                 int tag = info.tag;
--- a/src/share/classes/com/sun/tools/javap/BasicWriter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/BasicWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -71,6 +71,18 @@
         lineWriter.println();
     }
 
+    protected void indent(int delta) {
+        lineWriter.indent(delta);
+    }
+
+    protected void tab() {
+        lineWriter.tab();
+    }
+
+    protected void setPendingNewline(boolean b) {
+        lineWriter.pendingNewline = b;
+    }
+
     protected String report(AttributeException e) {
         out.println("Error: " + e.getMessage()); // i18n?
         return "???";
@@ -122,19 +134,30 @@
 
         protected LineWriter(Context context) {
             context.put(LineWriter.class, this);
+            Options options = Options.instance(context);
+            indentWidth = options.indentWidth;
+            tabColumn = options.tabColumn;
             out = context.get(PrintWriter.class);
             buffer = new StringBuilder();
         }
 
         protected void print(String s) {
+            if (pendingNewline) {
+                println();
+                pendingNewline = false;
+            }
             if (s == null)
                 s = "null";
             for (int i = 0; i < s.length(); i++) {
                 char c = s.charAt(i);
-                if (c == '\n') {
-                    println();
-                } else {
-                    buffer.append(c);
+                switch (c) {
+                    case '\n':
+                        println();
+                        break;
+                    default:
+                        if (buffer.length() == 0)
+                            indent();
+                        buffer.append(c);
                 }
             }
 
@@ -145,8 +168,31 @@
             buffer.setLength(0);
         }
 
+        protected void indent(int delta) {
+            indentCount += delta;
+        }
+
+        protected void tab() {
+            if (buffer.length() == 0)
+                indent();
+            space(indentCount * indentWidth + tabColumn - buffer.length());
+        }
+
+        private void indent() {
+            space(indentCount * indentWidth);
+        }
+
+        private void space(int n) {
+            for (int i = 0; i < n; i++)
+                buffer.append(' ');
+        }
+
         private PrintWriter out;
         private StringBuilder buffer;
+        private int indentCount;
+        private int indentWidth;
+        private int tabColumn;
+        private boolean pendingNewline;
     }
 }
 
--- a/src/share/classes/com/sun/tools/javap/ClassWriter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/ClassWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -120,6 +120,7 @@
                 else
                     println("Classfile " + uri);
             }
+            indent(+1);
             if (lastModified != -1) {
                 Date lm = new Date(lastModified);
                 DateFormat df = DateFormat.getDateInstance();
@@ -144,6 +145,10 @@
             println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\"");
         }
 
+        if ((options.sysInfo || options.verbose) && !options.compat) {
+            indent(-1);
+        }
+
         String name = getJavaName(classFile);
         AccessFlags flags = cf.access_flags;
 
@@ -186,23 +191,24 @@
 
         if (options.verbose) {
             println();
+            indent(+1);
             attrWriter.write(cf, cf.attributes, constant_pool);
-            println("  minor version: " + cf.minor_version);
-            println("  major version: " + cf.major_version);
+            println("minor version: " + cf.minor_version);
+            println("major version: " + cf.major_version);
             if (!options.compat)
-              writeList("  flags: ", flags.getClassFlags(), NEWLINE);
+              writeList("flags: ", flags.getClassFlags(), NEWLINE);
+            indent(-1);
             constantWriter.writeConstantPool();
-            println();
         } else {
-            if (!options.compat)
-                print(" ");
+            print(" ");
         }
 
         println("{");
+        indent(+1);
         writeFields();
         writeMethods();
+        indent(-1);
         println("}");
-        println();
     }
 
     protected void writeFields() {
@@ -215,14 +221,6 @@
         if (!options.checkAccess(f.access_flags))
             return;
 
-        if (!(options.showLineAndLocalVariableTables
-                || options.showDisassembled
-                || options.verbose
-                || options.showInternalSignatures
-                || options.showAllAttrs)) {
-            print("    ");
-        }
-
         AccessFlags flags = f.access_flags;
         writeModifiers(flags.getFieldModifiers());
         Signature_attribute sigAttr = getSignature(f.attributes);
@@ -251,11 +249,13 @@
         print(";");
         println();
 
+        indent(+1);
+
         if (options.showInternalSignatures)
-            println("  Signature: " + getValue(f.descriptor));
+            println("Signature: " + getValue(f.descriptor));
 
         if (options.verbose && !options.compat)
-            writeList("  flags: ", flags.getFieldFlags(), NEWLINE);
+            writeList("flags: ", flags.getFieldFlags(), NEWLINE);
 
         if (options.showAllAttrs) {
             for (Attribute attr: f.attributes)
@@ -263,6 +263,8 @@
             println();
         }
 
+        indent(-1);
+
         if (options.showDisassembled || options.showLineAndLocalVariableTables)
             println();
     }
@@ -270,6 +272,7 @@
     protected void writeMethods() {
         for (Method m: classFile.methods)
             writeMethod(m);
+        setPendingNewline(false);
     }
 
     protected void writeMethod(Method m) {
@@ -278,14 +281,6 @@
 
         method = m;
 
-        if (!(options.showLineAndLocalVariableTables
-                || options.showDisassembled
-                || options.verbose
-                || options.showInternalSignatures
-                || options.showAllAttrs)) {
-            print("    ");
-        }
-
         AccessFlags flags = m.access_flags;
 
         Descriptor d;
@@ -333,16 +328,6 @@
         if (e_attr != null) { // if there are generic exceptions, there must be erased exceptions
             if (e_attr instanceof Exceptions_attribute) {
                 Exceptions_attribute exceptions = (Exceptions_attribute) e_attr;
-                if (options.compat) { // Bug XXXXXXX whitespace
-                    if (!(options.showLineAndLocalVariableTables
-                            || options.showDisassembled
-                            || options.verbose
-                            || options.showInternalSignatures
-                            || options.showAllAttrs)) {
-                        print("    ");
-                    }
-                    print("  ");
-                }
                 print(" throws ");
                 if (methodExceptions != null) { // use generic list if available
                     writeList("", methodExceptions, "");
@@ -358,14 +343,17 @@
             }
         }
 
-        print(";");
-        println();
+        println(";");
 
-        if (options.showInternalSignatures)
-            println("  Signature: " + getValue(m.descriptor));
+        indent(+1);
 
-        if (options.verbose && !options.compat)
-            writeList("  flags: ", flags.getMethodFlags(), NEWLINE);
+        if (options.showInternalSignatures) {
+            println("Signature: " + getValue(m.descriptor));
+        }
+
+        if (options.verbose && !options.compat) {
+            writeList("flags: ", flags.getMethodFlags(), NEWLINE);
+        }
 
         Code_attribute code = null;
         Attribute c_attr = m.attributes.get(Attribute.Code);
@@ -378,33 +366,35 @@
 
         if (options.showDisassembled && !options.showAllAttrs) {
             if (code != null) {
-                println("  Code:");
+                println("Code:");
                 codeWriter.writeInstrs(code);
                 codeWriter.writeExceptionTable(code);
             }
-            println();
         }
 
         if (options.showLineAndLocalVariableTables) {
-            if (code != null)
+            if (code != null) {
                 attrWriter.write(code, code.attributes.get(Attribute.LineNumberTable), constant_pool);
-            println();
-            if (code != null)
                 attrWriter.write(code, code.attributes.get(Attribute.LocalVariableTable), constant_pool);
-            println();
-            println();
+            }
         }
 
         if (options.showAllAttrs) {
             Attribute[] attrs = m.attributes.attrs;
             for (Attribute attr: attrs)
                 attrWriter.write(m, attr, constant_pool);
+        }
 
-//            // the following condition is to mimic old javap
-//            if (!(attrs.length > 0 &&
-//                    attrs[attrs.length - 1] instanceof Exceptions_attribute))
-            println();
-        }
+        indent(-1);
+
+        // set pendingNewline to write a newline before the next method (if any)
+        // if a separator is desired
+        setPendingNewline(
+                options.showDisassembled ||
+                options.showAllAttrs ||
+                options.showInternalSignatures ||
+                options.showLineAndLocalVariableTables ||
+                options.verbose);
     }
 
     void writeModifiers(Collection<String> items) {
--- a/src/share/classes/com/sun/tools/javap/CodeWriter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/CodeWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -64,15 +64,18 @@
         stackMapWriter = StackMapWriter.instance(context);
         localVariableTableWriter = LocalVariableTableWriter.instance(context);
         localVariableTypeTableWriter = LocalVariableTypeTableWriter.instance(context);
+        typeAnnotationWriter = TypeAnnotationWriter.instance(context);
         options = Options.instance(context);
     }
 
     void write(Code_attribute attr, ConstantPool constant_pool) {
-        println("  Code:");
+        println("Code:");
+        indent(+1);
         writeVerboseHeader(attr, constant_pool);
         writeInstrs(attr);
         writeExceptionTable(attr);
         attrWriter.write(attr, attr.attributes, constant_pool);
+        indent(-1);
     }
 
     public void writeVerboseHeader(Code_attribute attr, ConstantPool constant_pool) {
@@ -89,9 +92,9 @@
             argCount = report(e);
         }
 
-        println("   Stack=" + attr.max_stack +
-                ", Locals=" + attr.max_locals +
-                ", Args_size=" + argCount);
+        println("stack=" + attr.max_stack +
+                ", locals=" + attr.max_locals +
+                ", args_size=" + argCount);
 
     }
 
@@ -114,8 +117,7 @@
     }
 
     public void writeInstr(Instruction instr) {
-        print("   " + instr.getPC() + ":\t");
-        print(instr.getMnemonic());
+        print(String.format("%4d: %-12s ", instr.getPC(), instr.getMnemonic()));
         instr.accept(instructionPrinter, null);
         println();
     }
@@ -133,54 +135,62 @@
         }
 
         public Void visitBranch(Instruction instr, int offset, Void p) {
-            print("\t" + (instr.getPC() + offset));
+            print((instr.getPC() + offset));
             return null;
         }
 
         public Void visitConstantPoolRef(Instruction instr, int index, Void p) {
-            print("\t#" + index + "; //");
+            print("#" + index + ";");
+            tab();
+            print("// ");
             printConstant(index);
             return null;
         }
 
         public Void visitConstantPoolRefAndValue(Instruction instr, int index, int value, Void p) {
-            print("\t#" + index + ",  " + value + "; //");
+            print("#" + index + ",  " + value + ";");
+            tab();
+            print("// ");
             printConstant(index);
             return null;
         }
 
         public Void visitLocal(Instruction instr, int index, Void p) {
-            print("\t" + index);
+            print(index);
             return null;
         }
 
         public Void visitLocalAndValue(Instruction instr, int index, int value, Void p) {
-            print("\t" + index + ", " + value);
+            print(index + ", " + value);
             return null;
         }
 
         public Void visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets) {
             int pc = instr.getPC();
-            print("{ //" + npairs);
+            print("{ // " + npairs);
+            indent(+1);
             for (int i = 0; i < npairs; i++) {
-                print("\n\t\t" + matches[i] + ": " + (pc + offsets[i]) + ";");
+                print("\n" + matches[i] + ": " + (pc + offsets[i]) + ";");
             }
-            print("\n\t\tdefault: " + (pc + default_) + " }");
+            print("\ndefault: " + (pc + default_) + " }");
+            indent(-1);
             return null;
         }
 
         public Void visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets) {
             int pc = instr.getPC();
             print("{ //" + low + " to " + high);
+            indent(+1);
             for (int i = 0; i < offsets.length; i++) {
-                print("\n\t\t" + (low + i) + ": " + (pc + offsets[i]) + ";");
+                print("\n" + (low + i) + ": " + (pc + offsets[i]) + ";");
             }
-            print("\n\t\tdefault: " + (pc + default_) + " }");
+            print("\ndefault: " + (pc + default_) + " }");
+            indent(-1);
             return null;
         }
 
         public Void visitValue(Instruction instr, int value, Void p) {
-            print("\t" + value);
+            print(value);
             return null;
         }
 
@@ -192,13 +202,13 @@
 
     public void writeExceptionTable(Code_attribute attr) {
         if (attr.exception_table_langth > 0) {
-            println("  Exception table:");
-            println("   from   to  target type");
+            println("Exception table:");
+            indent(+1);
+            println(" from    to  target type");
             for (int i = 0; i < attr.exception_table.length; i++) {
                 Code_attribute.Exception_data handler = attr.exception_table[i];
-                printFixedWidthInt(handler.start_pc, 6);
-                printFixedWidthInt(handler.end_pc, 6);
-                printFixedWidthInt(handler.handler_pc, 6);
+                print(String.format(" %5d %5d %5d",
+                        handler.start_pc, handler.end_pc, handler.handler_pc));
                 print("   ");
                 int catch_type = handler.catch_type;
                 if (catch_type == 0) {
@@ -206,9 +216,9 @@
                 } else {
                     print("Class ");
                     println(constantWriter.stringValue(catch_type));
-                    println("");
                 }
             }
+            indent(-1);
         }
 
     }
@@ -217,13 +227,6 @@
         constantWriter.write(index);
     }
 
-    private void printFixedWidthInt(int n, int width) {
-        String s = String.valueOf(n);
-        for (int i = s.length(); i < width; i++)
-            print(" ");
-        print(s);
-    }
-
     private List<InstructionDetailWriter> getDetailWriters(Code_attribute attr) {
         List<InstructionDetailWriter> detailWriters =
                 new ArrayList<InstructionDetailWriter>();
@@ -253,6 +256,11 @@
             detailWriters.add(tryBlockWriter);
         }
 
+        if (options.details.contains(InstructionDetailWriter.Kind.TYPE_ANNOS)) {
+            typeAnnotationWriter.reset(attr);
+            detailWriters.add(typeAnnotationWriter);
+        }
+
         return detailWriters;
     }
 
@@ -261,6 +269,7 @@
     private ConstantWriter constantWriter;
     private LocalVariableTableWriter localVariableTableWriter;
     private LocalVariableTypeTableWriter localVariableTypeTableWriter;
+    private TypeAnnotationWriter typeAnnotationWriter;
     private SourceWriter sourceWriter;
     private StackMapWriter stackMapWriter;
     private TryBlockWriter tryBlockWriter;
--- a/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -62,7 +62,9 @@
     protected void writeConstantPool(ConstantPool constant_pool) {
         ConstantPool.Visitor<Integer, Void> v = new ConstantPool.Visitor<Integer,Void>() {
             public Integer visitClass(CONSTANT_Class_info info, Void p) {
-                println("#" + info.name_index + ";\t//  " + stringValue(info));
+                print("#" + info.name_index + ";");
+                tab();
+                println("//  " + stringValue(info));
                 return 1;
             }
 
@@ -72,7 +74,9 @@
             }
 
             public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) {
-                println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t//  " + stringValue(info));
+                print("#" + info.class_index + ".#" + info.name_and_type_index + ";");
+                tab();
+                println("//  " + stringValue(info));
                 return 1;
             }
 
@@ -87,7 +91,9 @@
             }
 
             public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
-                println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t//  " + stringValue(info));
+                print("#" + info.class_index + ".#" + info.name_and_type_index + ";");
+                tab();
+                println("//  " + stringValue(info));
                 return 1;
             }
 
@@ -97,18 +103,23 @@
             }
 
             public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
-                String tab = (options.compat ? "" : "\t"); // BUG 6622232 javap gets whitespace confused
-                println("#" + info.name_index + ":#" + info.type_index + ";" + tab + "//  " + stringValue(info));
+                print("#" + info.name_index + ":#" + info.type_index + ";");
+                tab();
+                println("//  " + stringValue(info));
                 return 1;
             }
 
             public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) {
-                println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t//  " + stringValue(info));
+                print("#" + info.class_index + ".#" + info.name_and_type_index + ";");
+                tab();
+                println("//  " + stringValue(info));
                 return 1;
             }
 
             public Integer visitString(CONSTANT_String_info info, Void p) {
-                println("#" + info.string_index + ";\t//  " + stringValue(info));
+                print("#" + info.string_index + ";");
+                tab();
+                println("//  " + stringValue(info));
                 return 1;
             }
 
@@ -118,17 +129,21 @@
             }
 
         };
-        println("  Constant pool:");
+        println("Constant pool:");
+        indent(+1);
+        int width = String.valueOf(constant_pool.size()).length() + 1;
         int cpx = 1;
         while (cpx < constant_pool.size()) {
+            print(String.format("const %" + width + "s", ("#" + cpx)));
             try {
                 CPInfo cpInfo = constant_pool.get(cpx);
-                print("const #" + cpx + " = " + tagName(cpInfo.getTag()) + "\t");
+                print(String.format(" = %-15s ", tagName(cpInfo.getTag())));
                 cpx += cpInfo.accept(v, null);
             } catch (ConstantPool.InvalidIndex ex) {
-                print("const #" + cpx); // should not happen
+                // should not happen
             }
         }
+        indent(-1);
     }
 
     protected void write(int cpx) {
--- a/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/InstructionDetailWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -42,7 +42,8 @@
         LOCAL_VAR_TYPES("localVariableTypes"),
         SOURCE("source"),
         STACKMAPS("stackMaps"),
-        TRY_BLOCKS("tryBlocks");
+        TRY_BLOCKS("tryBlocks"),
+        TYPE_ANNOS("typeAnnotations");
         Kind(String option) {
             this.option = option;
         }
--- a/src/share/classes/com/sun/tools/javap/JavapFileManager.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/JavapFileManager.java	Thu Aug 06 19:03:42 2009 -0700
@@ -41,13 +41,13 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-class JavapFileManager extends JavacFileManager {
+public class JavapFileManager extends JavacFileManager {
     private JavapFileManager(Context context, Charset charset) {
         super(context, true, charset);
         setIgnoreSymbolFile(true);
     }
 
-    static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log, Options options) {
+    public static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
         Context javac_context = new Context();
 
         if (dl != null)
--- a/src/share/classes/com/sun/tools/javap/JavapTask.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/JavapTask.java	Thu Aug 06 19:03:42 2009 -0700
@@ -32,8 +32,10 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.io.Reader;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.net.URI;
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
@@ -49,6 +51,8 @@
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.NestingKind;
 import javax.tools.Diagnostic;
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileManager;
@@ -57,6 +61,9 @@
 import javax.tools.StandardLocation;
 
 import com.sun.tools.classfile.*;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
 
 /**
  *  "Main" class for javap, normally accessed from the command line
@@ -289,6 +296,44 @@
             void process(JavapTask task, String opt, String arg) {
                 task.options.showConstants = true;
             }
+        },
+
+        new Option(false, "-XDinner") {
+            void process(JavapTask task, String opt, String arg) {
+                task.options.showInnerClasses = true;
+            }
+        },
+
+        new Option(false, "-XDindent:") {
+            @Override
+            boolean matches(String opt) {
+                int sep = opt.indexOf(":");
+                return sep != -1 && super.matches(opt.substring(0, sep + 1));
+            }
+
+            void process(JavapTask task, String opt, String arg) throws BadArgs {
+                int sep = opt.indexOf(":");
+                try {
+                    task.options.indentWidth = Integer.valueOf(opt.substring(sep + 1));
+                } catch (NumberFormatException e) {
+                }
+            }
+        },
+
+        new Option(false, "-XDtab:") {
+            @Override
+            boolean matches(String opt) {
+                int sep = opt.indexOf(":");
+                return sep != -1 && super.matches(opt.substring(0, sep + 1));
+            }
+
+            void process(JavapTask task, String opt, String arg) throws BadArgs {
+                int sep = opt.indexOf(":");
+                try {
+                    task.options.tabColumn = Integer.valueOf(opt.substring(sep + 1));
+                } catch (NumberFormatException e) {
+                }
+            }
         }
 
     };
@@ -316,17 +361,17 @@
             Iterable<String> classes) {
         this(out, fileManager, diagnosticListener);
 
+        this.classes = new ArrayList<String>();
+        for (String classname: classes) {
+            classname.getClass(); // null-check
+            this.classes.add(classname);
+        }
+
         try {
             handleOptions(options, false);
         } catch (BadArgs e) {
             throw new IllegalArgumentException(e.getMessage());
         }
-
-        this.classes = new ArrayList<String>();
-        for (String classname: classes) {
-            classname.getClass(); // null-check
-            this.classes.add(classname);
-        }
     }
 
     public void setLocale(Locale locale) {
@@ -372,10 +417,18 @@
         final PrintWriter pw = getPrintWriterForWriter(w);
         return new DiagnosticListener<JavaFileObject> () {
             public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
-                if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                switch (diagnostic.getKind()) {
+                    case ERROR:
                         pw.print(getMessage("err.prefix"));
-                    pw.print(" ");
+                        break;
+                    case WARNING:
+                        pw.print(getMessage("warn.prefix"));
+                        break;
+                    case NOTE:
+                        pw.print(getMessage("note.prefix"));
+                        break;
                 }
+                pw.print(" ");
                 pw.println(diagnostic.getMessage(null));
             }
         };
@@ -405,7 +458,7 @@
             boolean ok = run();
             return ok ? EXIT_OK : EXIT_ERROR;
         } catch (BadArgs e) {
-            diagnosticListener.report(createDiagnostic(e.key, e.args));
+            reportError(e.key, e.args);
             if (e.showUsage) {
                 log.println(getMessage("main.usage.summary", progname));
             }
@@ -419,7 +472,7 @@
                 e_args[0] = e.getCause();
                 System.arraycopy(e.args, 0, e_args, 1, e.args.length);
             }
-            diagnosticListener.report(createDiagnostic("err.internal.error", e_args));
+            reportError("err.internal.error", e_args);
             return EXIT_ABNORMAL;
         } finally {
             log.flush();
@@ -521,64 +574,37 @@
         SourceWriter sourceWriter = SourceWriter.instance(context);
         sourceWriter.setFileManager(fileManager);
 
+        attributeFactory.setCompat(options.compat);
+        attributeFactory.setJSR277(options.jsr277);
+
         boolean ok = true;
 
         for (String className: classes) {
             JavaFileObject fo;
             try {
-                if (className.endsWith(".class")) {
-                    if (fileManager instanceof StandardJavaFileManager) {
-                        StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
-                        fo = sfm.getJavaFileObjects(className).iterator().next();
-                    } else {
-                       diagnosticListener.report(createDiagnostic("err.not.standard.file.manager", className));
-                       ok = false;
-                       continue;
-                    }
-                } else {
-                    fo = getClassFileObject(className);
-                    if (fo == null) {
-                        // see if it is an inner class, by replacing dots to $, starting from the right
-                        String cn = className;
-                        int lastDot;
-                        while (fo == null && (lastDot = cn.lastIndexOf(".")) != -1) {
-                            cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1);
-                            fo = getClassFileObject(cn);
-                        }
-                    }
-                    if (fo == null) {
-                       diagnosticListener.report(createDiagnostic("err.class.not.found", className));
-                       ok = false;
-                       continue;
-                    }
-                }
-                attributeFactory.setCompat(options.compat);
-                attributeFactory.setJSR277(options.jsr277);
-
-                write(read(fo));
-
+                writeClass(classWriter, className);
             } catch (ConstantPoolException e) {
-                diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
+                reportError("err.bad.constant.pool", className, e.getLocalizedMessage());
                 ok = false;
             } catch (EOFException e) {
-                diagnosticListener.report(createDiagnostic("err.end.of.file", className));
+                reportError("err.end.of.file", className);
                 ok = false;
             } catch (FileNotFoundException e) {
-                diagnosticListener.report(createDiagnostic("err.file.not.found", e.getLocalizedMessage()));
+                reportError("err.file.not.found", e.getLocalizedMessage());
                 ok = false;
             } catch (IOException e) {
                 //e.printStackTrace();
                 Object msg = e.getLocalizedMessage();
                 if (msg == null)
                     msg = e;
-                diagnosticListener.report(createDiagnostic("err.ioerror", className, msg));
+                reportError("err.ioerror", className, msg);
                 ok = false;
             } catch (Throwable t) {
                 StringWriter sw = new StringWriter();
                 PrintWriter pw = new PrintWriter(sw);
                 t.printStackTrace(pw);
                 pw.close();
-                diagnosticListener.report(createDiagnostic("err.crash", t.toString(), sw.toString()));
+                reportError("err.crash", t.toString(), sw.toString());
                 ok = false;
             }
         }
@@ -586,6 +612,152 @@
         return ok;
     }
 
+    protected boolean writeClass(ClassWriter classWriter, String className)
+            throws IOException, ConstantPoolException {
+        JavaFileObject fo = open(className);
+        if (fo == null) {
+            reportError("err.class.not.found", className);
+            return false;
+        }
+
+        ClassFileInfo cfInfo = read(fo);
+        if (!className.endsWith(".class")) {
+            String cfName = cfInfo.cf.getName();
+            if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", ".")))
+                reportWarning("warn.unexpected.class", className, cfName.replace('/', '.'));
+        }
+        write(cfInfo);
+
+        if (options.showInnerClasses) {
+            ClassFile cf = cfInfo.cf;
+            Attribute a = cf.getAttribute(Attribute.InnerClasses);
+            if (a instanceof InnerClasses_attribute) {
+                InnerClasses_attribute inners = (InnerClasses_attribute) a;
+                try {
+                    boolean ok = true;
+                    for (int i = 0; i < inners.classes.length; i++) {
+                        int outerIndex = inners.classes[i].outer_class_info_index;
+                        ConstantPool.CONSTANT_Class_info outerClassInfo = cf.constant_pool.getClassInfo(outerIndex);
+                        String outerClassName = outerClassInfo.getName();
+                        if (outerClassName.equals(cf.getName())) {
+                            int innerIndex = inners.classes[i].inner_class_info_index;
+                            ConstantPool.CONSTANT_Class_info innerClassInfo = cf.constant_pool.getClassInfo(innerIndex);
+                            String innerClassName = innerClassInfo.getName();
+                            classWriter.println("// inner class " + innerClassName.replaceAll("[/$]", "."));
+                            classWriter.println();
+                            ok = ok & writeClass(classWriter, innerClassName);
+                        }
+                    }
+                    return ok;
+                } catch (ConstantPoolException e) {
+                    reportError("err.bad.innerclasses.attribute", className);
+                    return false;
+                }
+            } else if (a != null) {
+                reportError("err.bad.innerclasses.attribute", className);
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    protected JavaFileObject open(String className) throws IOException {
+        // for compatibility, first see if it is a class name
+        JavaFileObject fo = getClassFileObject(className);
+        if (fo != null)
+            return fo;
+
+        // see if it is an inner class, by replacing dots to $, starting from the right
+        String cn = className;
+        int lastDot;
+        while ((lastDot = cn.lastIndexOf(".")) != -1) {
+            cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1);
+            fo = getClassFileObject(cn);
+            if (fo != null)
+                return fo;
+        }
+
+        if (!className.endsWith(".class"))
+            return null;
+
+        if (fileManager instanceof StandardJavaFileManager) {
+            StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
+            fo = sfm.getJavaFileObjects(className).iterator().next();
+            if (fo != null && fo.getLastModified() != 0) {
+                return fo;
+            }
+        }
+
+        // see if it is a URL, and if so, wrap it in just enough of a JavaFileObject
+        // to suit javap's needs
+        if (className.matches("^[A-Za-z]+:.*")) {
+            try {
+                final URI uri = new URI(className);
+                final URL url = uri.toURL();
+                final URLConnection conn = url.openConnection();
+                return new JavaFileObject() {
+                    public Kind getKind() {
+                        return JavaFileObject.Kind.CLASS;
+                    }
+
+                    public boolean isNameCompatible(String simpleName, Kind kind) {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    public NestingKind getNestingKind() {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    public Modifier getAccessLevel() {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    public URI toUri() {
+                        return uri;
+                    }
+
+                    public String getName() {
+                        return url.toString();
+                    }
+
+                    public InputStream openInputStream() throws IOException {
+                        return conn.getInputStream();
+                    }
+
+                    public OutputStream openOutputStream() throws IOException {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    public Writer openWriter() throws IOException {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    public long getLastModified() {
+                        return conn.getLastModified();
+                    }
+
+                    public boolean delete() {
+                        throw new UnsupportedOperationException();
+                    }
+
+                };
+            } catch (URISyntaxException ignore) {
+            } catch (IOException ignore) {
+            }
+        }
+
+        return null;
+    }
+
     public static class ClassFileInfo {
         ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) {
             this.fo = fo;
@@ -684,7 +856,7 @@
     }
 
     private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
-        return JavapFileManager.create(dl, log, options);
+        return JavapFileManager.create(dl, log);
     }
 
     private JavaFileObject getClassFileObject(String className) throws IOException {
@@ -738,10 +910,23 @@
         }
     }
 
-    private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) {
+    private void reportError(String key, Object... args) {
+        diagnosticListener.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args));
+    }
+
+    private void reportNote(String key, Object... args) {
+        diagnosticListener.report(createDiagnostic(Diagnostic.Kind.NOTE, key, args));
+    }
+
+    private void reportWarning(String key, Object... args) {
+        diagnosticListener.report(createDiagnostic(Diagnostic.Kind.WARNING, key, args));
+    }
+
+    private Diagnostic<JavaFileObject> createDiagnostic(
+            final Diagnostic.Kind kind, final String key, final Object... args) {
         return new Diagnostic<JavaFileObject>() {
             public Kind getKind() {
-                return Diagnostic.Kind.ERROR;
+                return kind;
             }
 
             public JavaFileObject getSource() {
@@ -776,6 +961,11 @@
                 return JavapTask.this.getMessage(locale, key, args);
             }
 
+            @Override
+            public String toString() {
+                return getClass().getName() + "[key=" + key + ",args=" + Arrays.asList(args) + "]";
+            }
+
         };
 
     }
--- a/src/share/classes/com/sun/tools/javap/Options.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/Options.java	Thu Aug 06 19:03:42 2009 -0700
@@ -85,6 +85,9 @@
     public boolean showAllAttrs;
     public boolean showConstants;
     public boolean sysInfo;
+    public boolean showInnerClasses;
+    public int indentWidth = 2;   // #spaces per indentWidth level
+    public int tabColumn = 40;    // column number for comments
 
     public boolean compat;             // bug-for-bug compatibility mode with old javap
     public boolean jsr277;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javap/TypeAnnotationWriter.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.tools.javap;
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.ExtendedAnnotation;
+import com.sun.tools.classfile.ExtendedAnnotation.Position;
+import com.sun.tools.classfile.Instruction;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
+import com.sun.tools.classfile.RuntimeTypeAnnotations_attribute;
+import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Annotate instructions with details about type annotations.
+ *
+ *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
+ *  you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class TypeAnnotationWriter extends InstructionDetailWriter {
+    public enum NoteKind { VISIBLE, INVISIBLE };
+    public static class Note {
+        Note(NoteKind kind, ExtendedAnnotation anno) {
+            this.kind = kind;
+            this.anno = anno;
+        }
+        public final NoteKind kind;
+        public final ExtendedAnnotation anno;
+    }
+
+    static TypeAnnotationWriter instance(Context context) {
+        TypeAnnotationWriter instance = context.get(TypeAnnotationWriter.class);
+        if (instance == null)
+            instance = new TypeAnnotationWriter(context);
+        return instance;
+    }
+
+    protected TypeAnnotationWriter(Context context) {
+        super(context);
+        context.put(TypeAnnotationWriter.class, this);
+        annotationWriter = AnnotationWriter.instance(context);
+        classWriter = ClassWriter.instance(context);
+    }
+
+    public void reset(Code_attribute attr) {
+        Method m = classWriter.getMethod();
+        pcMap = new HashMap<Integer, List<Note>>();
+        check(NoteKind.VISIBLE, (RuntimeVisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeVisibleTypeAnnotations));
+        check(NoteKind.INVISIBLE, (RuntimeInvisibleTypeAnnotations_attribute) m.attributes.get(Attribute.RuntimeInvisibleTypeAnnotations));
+    }
+
+    private void check(NoteKind kind, RuntimeTypeAnnotations_attribute attr) {
+        if (attr == null)
+            return;
+
+        for (ExtendedAnnotation anno: attr.annotations) {
+            Position p = anno.position;
+            Note note = null;
+            if (p.offset != -1)
+                addNote(p.offset, note = new Note(kind, anno));
+            if (p.lvarOffset != null) {
+                for (int i = 0; i < p.lvarOffset.length; i++) {
+                    if (note == null)
+                        note = new Note(kind, anno);
+                    addNote(p.lvarOffset[i], note);
+                }
+            }
+        }
+    }
+
+    private void addNote(int pc, Note note) {
+        List<Note> list = pcMap.get(pc);
+        if (list == null)
+            pcMap.put(pc, list = new ArrayList<Note>());
+        list.add(note);
+    }
+
+    @Override
+    void writeDetails(Instruction instr) {
+        String indent = space(2); // get from Options?
+        int pc = instr.getPC();
+        List<Note> notes = pcMap.get(pc);
+        if (notes != null) {
+            for (Note n: notes) {
+                print(indent);
+                print("@");
+                annotationWriter.write(n.anno, false, true);
+                print(", ");
+                println(n.kind.toString().toLowerCase());
+            }
+        }
+    }
+
+    private AnnotationWriter annotationWriter;
+    private ClassWriter classWriter;
+    private Map<Integer, List<Note>> pcMap;
+}
--- a/src/share/classes/com/sun/tools/javap/resources/javap.properties	Thu Aug 06 10:25:29 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/resources/javap.properties	Thu Aug 06 19:03:42 2009 -0700
@@ -18,12 +18,22 @@
 err.verify.not.supported=-verify not supported
 err.no.SourceFile.attribute=no SourceFile attribute
 err.source.file.not.found=source file not found
+err.bad.innerclasses.attribute=bad InnerClasses attribute for {0}
 warn.Xold.not.supported=-Xold is no longer available
 
 main.usage.summary=\
 Usage: {0} <options> <classes>\n\
 use -help for a list of possible options
 
+warn.prefix=Warning:
+warn.unexpected.class=Binary file {0} contains {1}
+
+note.prefix=Note:
+
+main.usage.summary=\
+Usage: {0} <options> <classes>\n\
+use -help for a list of possible options
+
 main.usage=\
 Usage: {0} <options> <classes>\n\
 where possible options include:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/Diagnostics/6862608/T6862608a.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug     6862608
+ * @summary rich diagnostic sometimes contain wrong type variable numbering
+ * @author  mcimadamore
+ * @compile/fail/ref=T6862608a.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T6862608a.java
+ */
+
+
+import java.util.*;
+
+class T6862608a {
+
+    <T> Comparator<T> compound(Iterable<? extends Comparator<? super T>> it) {
+        return null;
+    }
+
+    public void test(List<Comparator<?>> x) {
+        Comparator<String> c3 = compound(x);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/Diagnostics/6862608/T6862608a.out	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,3 @@
+T6862608a.java:42:41: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.params: java.lang.Iterable<? extends java.util.Comparator<? super java.lang.String>>, java.util.List<java.util.Comparator<?>>)
+- compiler.misc.where.description.typevar: T,{(compiler.misc.where.typevar: T, java.lang.Object, kindname.method, <T>compound(java.lang.Iterable<? extends java.util.Comparator<? super T>>))}
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/Diagnostics/6862608/T6862608b.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug     6862608
+ * @summary rich diagnostic sometimes contain wrong type variable numbering
+ * @author  mcimadamore
+ * @compile/fail/ref=T6862608b.out -XDrawDiagnostics -XDdiags=disambiguateTvars,where T6862608b.java
+ */
+
+class T66862608b<T extends String, S> {
+   <S, T extends S> void foo(T t) {
+      test(t);
+   }
+
+   void test(T t) {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/Diagnostics/6862608/T6862608b.out	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,3 @@
+T6862608b.java:34:7: compiler.err.cant.apply.symbol: kindname.method, test, compiler.misc.type.var: T, 1, compiler.misc.type.var: T, 2, kindname.class, T66862608b<compiler.misc.type.var: T, 1,compiler.misc.type.var: S, 2>, null
+- compiler.misc.where.description.typevar.1: compiler.misc.type.var: T, 1,compiler.misc.type.var: T, 2,compiler.misc.type.var: S, 1,compiler.misc.type.var: S, 2,{(compiler.misc.where.typevar: compiler.misc.type.var: T, 1, java.lang.String, kindname.class, T66862608b),(compiler.misc.where.typevar: compiler.misc.type.var: T, 2, compiler.misc.type.var: S, 1, kindname.method, <compiler.misc.type.var: S, 1,compiler.misc.type.var: T, 2>foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 1, java.lang.Object, kindname.method, <compiler.misc.type.var: S, 1,compiler.misc.type.var: T, 2>foo(compiler.misc.type.var: T, 2)),(compiler.misc.where.typevar: compiler.misc.type.var: S, 2, java.lang.Object, kindname.class, T66862608b)}
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/Diagnostics/6864382/T6864382.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug     6864382
+ * @summary NullPointerException when compiling a negative java source
+ * @author  mcimadamore
+ * @compile/fail/ref=T6864382.out -XDrawDiagnostics  T6864382.java
+ */
+
+class T6864382<T> extends T {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/Diagnostics/6864382/T6864382.out	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,2 @@
+T6864382.java:32:27: compiler.err.type.found.req: (compiler.misc.type.parameter: T), (compiler.misc.type.req.class)
+1 error
--- a/test/tools/javac/code/ArrayClone.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/test/tools/javac/code/ArrayClone.java	Thu Aug 06 19:03:42 2009 -0700
@@ -48,7 +48,7 @@
         System.out.println(out);
 
         for (String line: out.split("\n")) {
-            String match = "[ \t]+[0-9]+:[ \t]+invokevirtual[ \t]+#[0-9]+; //Method \"\\[Ljava/lang/String;\".clone:\\(\\)Ljava/lang/Object;";
+            String match = "[ \t]+[0-9]+:[ \t]+invokevirtual[ \t]+#[0-9]+;[ \t]+// Method \"\\[Ljava/lang/String;\".clone:\\(\\)Ljava/lang/Object;";
             if (line.matches(match))
                 return;
         }
--- a/test/tools/javac/typeAnnotations/InnerClass.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/test/tools/javac/typeAnnotations/InnerClass.java	Thu Aug 06 19:03:42 2009 -0700
@@ -30,9 +30,30 @@
  */
 
 class InnerClass {
+
+    InnerClass() {}
+    InnerClass(Object o) {}
+
     private void a() {
         new Object() {
             public <R> void method() { }
         };
     }
+
+    Object f1 = new InnerClass() {
+            <R> void method() { }
+        };
+
+    Object f2 = new InnerClass() {
+            <@A R> void method() { }
+        };
+
+    Object f3 = new InnerClass(null) {
+            <R> void method() { }
+        };
+
+    Object f4 = new InnerClass(null) {
+            <@A R> void method() { }
+        };
+    @interface A { }
 }
--- a/test/tools/javap/4111861/T4111861.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/test/tools/javap/4111861/T4111861.java	Thu Aug 06 19:03:42 2009 -0700
@@ -89,7 +89,7 @@
             String line;
             while ((line = in.readLine()) != null) {
                 if (line.indexOf("public static final") > 0) {
-                    sb.append(line);
+                    sb.append(line.trim());
                     sb.append('\n');
                 }
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javap/T4777949.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.tools.*;
+import com.sun.tools.javap.*;
+
+/*
+ * @test
+ * @bug 4777949
+ * @summary Warn javap usage on package with simple name
+ */
+public class T4777949 {
+    public static void main(String... args) throws Exception {
+        new T4777949().run();
+    }
+
+    void run() throws Exception {
+        File javaFile = writeTestFile();
+        File classFile = compileTestFile(javaFile);
+
+        test(".", "p.q.r.Test", false);
+        test("p", "q.r.Test", true);
+        test("p/q", "r.Test", true);
+        test("p/q/r", "Test", true);
+        test(".", "p.q.r.Test.Inner", false);
+        test(".", "p.q.r.Test$Inner", false);
+        test("p", "q.r.Test.Inner", true);
+        test("p", "q.r.Test$Inner", true);
+
+        if (errors > 0)
+            throw new Exception(errors + " errors found");
+    }
+
+    void test(String classPath, String className, boolean expectWarnings) {
+        List<Diagnostic<? extends JavaFileObject>> diags =
+            javap(Arrays.asList("-classpath", classPath), Arrays.asList(className));
+        boolean foundWarnings = false;
+        for (Diagnostic<? extends JavaFileObject> d: diags) {
+            if (d.getKind() == Diagnostic.Kind.WARNING)
+                foundWarnings = true;
+        }
+    }
+
+
+    File writeTestFile() throws IOException {
+        File f = new File("Test.java");
+        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
+        out.println("package p.q.r;");
+        out.println("class Test { class Inner { } }");
+        out.close();
+        return f;
+    }
+
+    File compileTestFile(File f) {
+        int rc = com.sun.tools.javac.Main.compile(new String[] { "-d", ".", f.getPath() });
+        if (rc != 0)
+            throw new Error("compilation failed. rc=" + rc);
+        String path = f.getPath();
+        return new File(path.substring(0, path.length() - 5) + ".class");
+    }
+
+    List<Diagnostic<? extends JavaFileObject>> javap(List<String> args, List<String> classes) {
+        DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>();
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        JavaFileManager fm = JavapFileManager.create(dc, pw);
+        JavapTask t = new JavapTask(pw, fm, dc, args, classes);
+        boolean ok = t.run();
+
+        List<Diagnostic<? extends JavaFileObject>> diags = dc.getDiagnostics();
+
+        if (!ok)
+            error("javap failed unexpectedly");
+
+        System.err.println("args=" + args + " classes=" + classes + "\n"
+                           + diags + "\n"
+                           + sw);
+
+        return diags;
+    }
+
+    void error(String msg) {
+        System.err.println("error: " + msg);
+        errors++;
+    }
+
+    int errors;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javap/T4880672.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/*
+ * @test
+ * @bug 4880672
+ * @summary javap does not output inner interfaces of an interface
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class T4880672
+{
+    public static void main(String... args) {
+        new T4880672().run();
+    }
+
+    void run() {
+        verify("java.util.Map", "public interface java.util.Map$Entry");
+        verify("T4880672", "class T4880672$A$B extends java.lang.Object");
+        verify("C", ""); // must not give error if no InnerClasses attribute
+        if (errors > 0)
+            throw new Error(errors + " found.");
+    }
+
+    void verify(String className, String... expects) {
+        String output = javap(className);
+        for (String expect: expects) {
+            if (output.indexOf(expect)< 0)
+                error(expect + " not found");
+        }
+    }
+
+    void error(String msg) {
+        System.err.println(msg);
+        errors++;
+    }
+
+    int errors;
+
+    String javap(String className) {
+        String testClasses = System.getProperty("test.classes", ".");
+        StringWriter sw = new StringWriter();
+        PrintWriter out = new PrintWriter(sw);
+        String[] args = { "-XDinner", "-classpath", testClasses, className };
+        int rc = com.sun.tools.javap.Main.run(args, out);
+        out.close();
+        String output = sw.toString();
+        System.out.println("class " + className);
+        System.out.println(output);
+        if (rc != 0)
+            throw new Error("javap failed. rc=" + rc);
+        if (output.indexOf("Error:") != -1)
+            throw new Error("javap reported error.");
+        return output;
+    }
+
+    class A {
+        class B { }
+    }
+}
+
+class C { }
+
--- a/test/tools/javap/T4884240.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/test/tools/javap/T4884240.java	Thu Aug 06 19:03:42 2009 -0700
@@ -46,9 +46,9 @@
         pw.close();
         String[] lines = sw.toString().split("\n");
         if (lines.length < 3
-            || !lines[0].startsWith("Classfile")
-            || !lines[1].startsWith("Last modified")
-            || !lines[2].startsWith("MD5")) {
+            || !lines[0].trim().startsWith("Classfile")
+            || !lines[1].trim().startsWith("Last modified")
+            || !lines[2].trim().startsWith("MD5")) {
             System.out.println(sw);
             throw new Exception("unexpected output");
         }
--- a/test/tools/javap/T4975569.java	Thu Aug 06 10:25:29 2009 -0700
+++ b/test/tools/javap/T4975569.java	Thu Aug 06 19:03:42 2009 -0700
@@ -40,10 +40,10 @@
         verify("T4975569$Anno", "flags: ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION");
         verify("T4975569$E",    "flags: ACC_FINAL, ACC_SUPER, ACC_ENUM");
         verify("T4975569$S",    "flags: ACC_BRIDGE, ACC_SYNTHETIC",
-                                "InnerClasses: \n   static");
+                                "InnerClasses:\n       static");
         verify("T4975569$V",    "void m(java.lang.String...)",
                                 "flags: ACC_VARARGS");
-        verify("T4975569$Prot", "InnerClasses: \n   protected");
+        verify("T4975569$Prot", "InnerClasses:\n       protected");
         //verify("T4975569$Priv", "InnerClasses");
         if (errors > 0)
             throw new Error(errors + " found.");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javap/T6729471.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/*
+ * @test
+ * @bug 6729471
+ * @summary javap does not output inner interfaces of an interface
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class T6729471
+{
+    public static void main(String... args) {
+        new T6729471().run();
+    }
+
+    void run() {
+        // simple class
+        verify("java.util.Map",
+                "public abstract boolean containsKey(java.lang.Object)");
+
+        // inner class
+        verify("java.util.Map.Entry",
+                "public abstract K getKey()");
+
+        // file name
+        verify("../classes/tools/javap/T6729471.class",
+                "public static void main(java.lang.String...)");
+
+        // file url
+        verify("file:../classes/tools/javap/T6729471.class",
+                "public static void main(java.lang.String...)");
+
+        // jar url: rt.jar
+        File java_home = new File(System.getProperty("java.home"));
+        if (java_home.getName().equals("jre"))
+            java_home = java_home.getParentFile();
+        File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
+        verify("jar:file:" + rt_jar + "!/java/util/Map.class",
+                "public abstract boolean containsKey(java.lang.Object)");
+
+        // jar url: ct.sym, if it exists
+        File ct_sym = new File(new File(java_home, "lib"), "ct.sym");
+        if (ct_sym.exists()) {
+            verify("jar:file:" + ct_sym + "!/META-INF/sym/rt.jar/java/util/Map.class",
+                "public abstract boolean containsKey(java.lang.Object)");
+        } else
+            System.err.println("warning: ct.sym not found");
+
+        if (errors > 0)
+            throw new Error(errors + " found.");
+    }
+
+    void verify(String className, String... expects) {
+        String output = javap(className);
+        for (String expect: expects) {
+            if (output.indexOf(expect)< 0)
+                error(expect + " not found");
+        }
+    }
+
+    void error(String msg) {
+        System.err.println(msg);
+        errors++;
+    }
+
+    int errors;
+
+    String javap(String className) {
+        String testClasses = System.getProperty("test.classes", ".");
+        StringWriter sw = new StringWriter();
+        PrintWriter out = new PrintWriter(sw);
+        String[] args = { "-classpath", testClasses, className };
+        int rc = com.sun.tools.javap.Main.run(args, out);
+        out.close();
+        String output = sw.toString();
+        System.out.println("class " + className);
+        System.out.println(output);
+        if (rc != 0)
+            throw new Error("javap failed. rc=" + rc);
+        if (output.indexOf("Error:") != -1)
+            throw new Error("javap reported error.");
+        return output;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javap/T6866657.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+/*
+ * @test
+ * @bug 6866657
+ * @summary add byteLength() method to primary classfile types
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.tools.*;
+import com.sun.tools.javap.*;
+
+public class T6866657
+{
+    public static void main(String... args) {
+        new T6866657().run();
+    }
+
+    void run() {
+        verify("java.lang.Object");
+        verify("java.lang.String");
+        verify("java.util.List");
+        verify("java.util.ArrayList");
+        if (errors > 0)
+            throw new Error(errors + " found.");
+    }
+
+    void verify(String className) {
+        try {
+            PrintWriter log = new PrintWriter(System.out);
+            JavaFileManager fileManager = JavapFileManager.create(null, log);
+            JavaFileObject fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
+            if (fo == null) {
+                error("Can't find " + className);
+            } else {
+                JavapTask t = new JavapTask(log, fileManager, null);
+                t.handleOptions(new String[] { "-sysinfo", className });
+                JavapTask.ClassFileInfo cfInfo = t.read(fo);
+                expectEqual(cfInfo.cf.byteLength(), cfInfo.size);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            error("Exception: " + e);
+        }
+    }
+
+    void expectEqual(int found, int expected) {
+        if (found != expected)
+            error("bad value found: " + found + " expected: " + expected);
+    }
+
+    void error(String msg) {
+        System.err.println(msg);
+        errors++;
+    }
+
+    int errors;
+}
+
--- a/test/tools/javap/stackmap/T6271292.sh	Thu Aug 06 10:25:29 2009 -0700
+++ b/test/tools/javap/stackmap/T6271292.sh	Thu Aug 06 19:03:42 2009 -0700
@@ -75,7 +75,7 @@
 grep "offset_delta" "${JAVAPFILE}" >> "${OUTFILE}"
 grep "stack = " "${JAVAPFILE}" >> "${OUTFILE}"
 grep "locals = " "${JAVAPFILE}" >> "${OUTFILE}"
-diff "${OUTFILE}" "${TESTSRC}${FS}T6271292.out"
+diff -w "${OUTFILE}" "${TESTSRC}${FS}T6271292.out"
 result="$?"
 if [ "$result" -eq 0 ]
 then
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javap/typeAnnotations/T6855990.java	Thu Aug 06 19:03:42 2009 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.io.*;
+
+/*
+ * @test
+ * @bug 6855990
+ * @summary InstructionDetailWriter should support new 308 annotations attribute
+ */
+
+public class T6855990 {
+    public static void main(String[] args) throws Exception {
+        new T6855990().run();
+    }
+
+    public void run() throws Exception {
+        @Simple String[] args = { "-c", "-XDdetails:typeAnnotations", "T6855990" };
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javap.Main.run(args, pw);
+        pw.close();
+        String out = sw.toString();
+        System.out.println(out);
+        if (out.indexOf("@Simple: LOCAL_VARIABLE") == -1)
+            throw new Exception("expected output not found");
+    }
+}
+
+@interface Simple { }
+