changeset 305:e71fd3fcebf5

Merge
author tbell
date Fri, 26 Jun 2009 10:26:27 -0700
parents 5c2c81120555 812d5486a023
children c391a167ac57
files
diffstat 38 files changed, 1152 insertions(+), 379 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Fri Jun 26 10:26:27 2009 -0700
@@ -58,7 +58,7 @@
     public static final int ACC_ENUM          = 0x4000; // class, inner, field
     public static final int ACC_MODULE        = 0x8000; // class, inner, field, method
 
-    private static enum Type { Class, InnerClass, Field, Method};
+    public static enum Kind { Class, InnerClass, Field, Method};
 
     AccessFlags(ClassReader cr) throws IOException {
         this(cr.readUnsignedShort());
@@ -87,11 +87,11 @@
 
     public Set<String> getClassModifiers() {
         int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
-        return getModifiers(f, classModifiers, Type.Class);
+        return getModifiers(f, classModifiers, Kind.Class);
     }
 
     public Set<String> getClassFlags() {
-        return getFlags(classFlags, Type.Class);
+        return getFlags(classFlags, Kind.Class);
     }
 
     private static final int[] innerClassModifiers = {
@@ -106,11 +106,11 @@
 
     public Set<String> getInnerClassModifiers() {
         int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
-        return getModifiers(f, innerClassModifiers, Type.InnerClass);
+        return getModifiers(f, innerClassModifiers, Kind.InnerClass);
     }
 
     public Set<String> getInnerClassFlags() {
-        return getFlags(innerClassFlags, Type.InnerClass);
+        return getFlags(innerClassFlags, Kind.InnerClass);
     }
 
     private static final int[] fieldModifiers = {
@@ -124,11 +124,11 @@
     };
 
     public Set<String> getFieldModifiers() {
-        return getModifiers(fieldModifiers, Type.Field);
+        return getModifiers(fieldModifiers, Kind.Field);
     }
 
     public Set<String> getFieldFlags() {
-        return getFlags(fieldFlags, Type.Field);
+        return getFlags(fieldFlags, Kind.Field);
     }
 
     private static final int[] methodModifiers = {
@@ -143,18 +143,18 @@
     };
 
     public Set<String> getMethodModifiers() {
-        return getModifiers(methodModifiers, Type.Method);
+        return getModifiers(methodModifiers, Kind.Method);
     }
 
     public Set<String> getMethodFlags() {
-        return getFlags(methodFlags, Type.Method);
+        return getFlags(methodFlags, Kind.Method);
     }
 
-    private Set<String> getModifiers(int[] modifierFlags, Type t) {
+    private Set<String> getModifiers(int[] modifierFlags, Kind t) {
         return getModifiers(flags, modifierFlags, t);
     }
 
-    private static Set<String> getModifiers(int flags, int[] modifierFlags, Type t) {
+    private static Set<String> getModifiers(int flags, int[] modifierFlags, Kind t) {
         Set<String> s = new LinkedHashSet<String>();
         for (int m: modifierFlags) {
             if ((flags & m) != 0)
@@ -163,7 +163,7 @@
         return s;
     }
 
-    private Set<String> getFlags(int[] expectedFlags, Type t) {
+    private Set<String> getFlags(int[] expectedFlags, Kind t) {
         Set<String> s = new LinkedHashSet<String>();
         int f = flags;
         for (int e: expectedFlags) {
@@ -180,7 +180,7 @@
         return s;
     }
 
-    private static String flagToModifier(int flag, Type t) {
+    private static String flagToModifier(int flag, Kind t) {
         switch (flag) {
             case ACC_PUBLIC:
                 return "public";
@@ -195,7 +195,7 @@
             case ACC_SYNCHRONIZED:
                 return "synchronized";
             case 0x80:
-                return (t == Type.Field ? "transient" : null);
+                return (t == Kind.Field ? "transient" : null);
             case ACC_VOLATILE:
                 return "volatile";
             case ACC_NATIVE:
@@ -211,7 +211,7 @@
         }
     }
 
-    private static String flagToName(int flag, Type t) {
+    private static String flagToName(int flag, Kind t) {
         switch (flag) {
         case ACC_PUBLIC:
             return "ACC_PUBLIC";
@@ -224,11 +224,11 @@
         case ACC_FINAL:
             return "ACC_FINAL";
         case 0x20:
-            return (t == Type.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
+            return (t == Kind.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
         case 0x40:
-            return (t == Type.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
+            return (t == Kind.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
         case 0x80:
-            return (t == Type.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
+            return (t == Kind.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
         case ACC_NATIVE:
             return "ACC_NATIVE";
         case ACC_INTERFACE:
@@ -250,5 +250,5 @@
         }
     }
 
-    final int flags;
+    public final int flags;
 }
--- a/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Fri Jun 26 10:26:27 2009 -0700
@@ -573,6 +573,11 @@
             return visitor.visitNameAndType(this, data);
         }
 
+        @Override
+        public String toString() {
+            return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";
+        }
+
         public final int name_index;
         public final int type_index;
     }
@@ -600,6 +605,11 @@
             return visitor.visitString(this, data);
         }
 
+        @Override
+        public String toString() {
+            return "CONSTANT_String_info[class_index: " + string_index + "]";
+        }
+
         public final int string_index;
     }
 
@@ -618,7 +628,19 @@
 
         @Override
         public String toString() {
-            return "CONSTANT_Utf8_info[value: " + value + "]";
+            if (value.length() < 32 && isPrintableAscii(value))
+                return "CONSTANT_Utf8_info[value: \"" + value + "\"]";
+            else
+                return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";
+        }
+
+        static boolean isPrintableAscii(String s) {
+            for (int i = 0; i < s.length(); i++) {
+                char c = s.charAt(i);
+                if (c < 32 || c >= 127)
+                    return false;
+            }
+            return true;
         }
 
         public <R, D> R accept(Visitor<R, D> visitor, D data) {
--- a/src/share/classes/com/sun/tools/javac/code/Kinds.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Kinds.java	Fri Jun 26 10:26:27 2009 -0700
@@ -95,6 +95,7 @@
         ANNOTATION("kindname.interface"),
         CONSTRUCTOR("kindname.constructor"),
         INTERFACE("kindname.interface"),
+        ENUM("kindname.enum"),
         STATIC("kindname.static"),
         TYPEVAR("kindname.type.variable"),
         BOUND("kindname.type.variable.bound"),
@@ -145,11 +146,15 @@
             return KindName.PACKAGE;
 
         case ENUM:
+            return KindName.ENUM;
+
         case ANNOTATION_TYPE:
-        case INTERFACE:
         case CLASS:
             return KindName.CLASS;
 
+        case INTERFACE:
+            return KindName.INTERFACE;
+
         case TYPE_PARAMETER:
             return KindName.TYPEVAR;
 
@@ -160,8 +165,10 @@
         case EXCEPTION_PARAMETER:
             return KindName.VAR;
 
+        case CONSTRUCTOR:
+            return KindName.CONSTRUCTOR;
+
         case METHOD:
-        case CONSTRUCTOR:
         case STATIC_INIT:
         case INSTANCE_INIT:
             return KindName.METHOD;
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Fri Jun 26 10:26:27 2009 -0700
@@ -1066,6 +1066,21 @@
             return qtype.isErroneous();
         }
 
+        /**
+         * Replaces this ForAll's typevars with a set of concrete Java types
+         * and returns the instantiated generic type. Subclasses might override
+         * in order to check that the list of types is a valid instantiation
+         * of the ForAll's typevars.
+         *
+         * @param actuals list of actual types
+         * @param types types instance
+         * @return qtype where all occurrences of tvars are replaced
+         * by types in actuals
+         */
+        public Type inst(List<Type> actuals, Types types) {
+            return types.subst(qtype, tvars, actuals);
+        }
+
         public Type map(Mapping f) {
             return f.apply(qtype);
         }
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Jun 26 10:26:27 2009 -0700
@@ -343,6 +343,14 @@
         if (s.tag >= firstPartialTag)
             return isSuperType(s, t);
 
+        if (s.isCompound()) {
+            for (Type s2 : interfaces(s).prepend(supertype(s))) {
+                if (!isSubtype(t, s2, capture))
+                    return false;
+            }
+            return true;
+        }
+
         Type lower = lowerBound(s);
         if (s != lower)
             return isSubtype(capture ? capture(t) : t, lower, false);
@@ -2870,6 +2878,14 @@
     /**
      * Capture conversion as specified by JLS 3rd Ed.
      */
+
+    public List<Type> capture(List<Type> ts) {
+        List<Type> buf = List.nil();
+        for (Type t : ts) {
+            buf = buf.prepend(capture(t));
+        }
+        return buf.reverse();
+    }
     public Type capture(Type t) {
         if (t.tag != CLASS)
             return t;
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jun 26 10:26:27 2009 -0700
@@ -303,7 +303,7 @@
 
     public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
         breakTree = tree;
-        JavaFileObject prev = log.useSource(null);
+        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
         try {
             attribExpr(expr, env);
         } catch (BreakAttr b) {
@@ -317,7 +317,7 @@
 
     public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) {
         breakTree = tree;
-        JavaFileObject prev = log.useSource(null);
+        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
         try {
             attribStat(stmt, env);
         } catch (BreakAttr b) {
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Jun 26 10:26:27 2009 -0700
@@ -391,6 +391,10 @@
                                      diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
                                      t, pt);
                 }
+            } catch (Infer.InvalidInstanceException ex) {
+                JCDiagnostic d = ex.getDiagnostic();
+                log.error(pos, "invalid.inferred.types", t.tvars, d);
+                return types.createErrorType(pt);
             }
         }
     }
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Jun 26 10:26:27 2009 -0700
@@ -29,6 +29,7 @@
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.util.JCDiagnostic;
 
 import static com.sun.tools.javac.code.TypeTags.*;
@@ -49,6 +50,7 @@
 
     Symtab syms;
     Types types;
+    Resolve rs;
     JCDiagnostic.Factory diags;
 
     public static Infer instance(Context context) {
@@ -62,48 +64,60 @@
         context.put(inferKey, this);
         syms = Symtab.instance(context);
         types = Types.instance(context);
+        rs = Resolve.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         ambiguousNoInstanceException =
             new NoInstanceException(true, diags);
         unambiguousNoInstanceException =
             new NoInstanceException(false, diags);
+        invalidInstanceException =
+            new InvalidInstanceException(diags);
+
     }
 
-    public static class NoInstanceException extends RuntimeException {
+    public static class InferenceException extends RuntimeException {
         private static final long serialVersionUID = 0;
 
-        boolean isAmbiguous; // exist several incomparable best instances?
-
         JCDiagnostic diagnostic;
         JCDiagnostic.Factory diags;
 
-        NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
+        InferenceException(JCDiagnostic.Factory diags) {
             this.diagnostic = null;
-            this.isAmbiguous = isAmbiguous;
             this.diags = diags;
         }
-        NoInstanceException setMessage(String key) {
-            this.diagnostic = diags.fragment(key);
+
+        InferenceException setMessage(String key, Object... args) {
+            this.diagnostic = diags.fragment(key, args);
             return this;
         }
-        NoInstanceException setMessage(String key, Object arg1) {
-            this.diagnostic = diags.fragment(key, arg1);
-            return this;
-        }
-        NoInstanceException setMessage(String key, Object arg1, Object arg2) {
-            this.diagnostic = diags.fragment(key, arg1, arg2);
-            return this;
-        }
-        NoInstanceException setMessage(String key, Object arg1, Object arg2, Object arg3) {
-            this.diagnostic = diags.fragment(key, arg1, arg2, arg3);
-            return this;
-        }
+
         public JCDiagnostic getDiagnostic() {
-            return diagnostic;
+             return diagnostic;
+         }
+    }
+
+    public static class NoInstanceException extends InferenceException {
+        private static final long serialVersionUID = 1;
+
+        boolean isAmbiguous; // exist several incomparable best instances?
+
+        NoInstanceException(boolean isAmbiguous, JCDiagnostic.Factory diags) {
+            super(diags);
+            this.isAmbiguous = isAmbiguous;
         }
     }
+
+    public static class InvalidInstanceException extends InferenceException {
+        private static final long serialVersionUID = 2;
+
+        InvalidInstanceException(JCDiagnostic.Factory diags) {
+            super(diags);
+        }
+    }
+
     private final NoInstanceException ambiguousNoInstanceException;
     private final NoInstanceException unambiguousNoInstanceException;
+    private final InvalidInstanceException invalidInstanceException;
 
 /***************************************************************************
  * Auxiliary type values and classes
@@ -158,8 +172,7 @@
                 that.inst = types.glb(that.hibounds);
         }
         if (that.inst == null ||
-            that.inst.isErroneous() ||
-            !types.isSubtypeUnchecked(that.inst, that.hibounds, warn))
+            that.inst.isErroneous())
             throw ambiguousNoInstanceException
                 .setMessage("no.unique.maximal.instance.exists",
                             that.qtype, that.hibounds);
@@ -234,7 +247,7 @@
      */
     public Type instantiateExpr(ForAll that,
                                 Type to,
-                                Warner warn) throws NoInstanceException {
+                                Warner warn) throws InferenceException {
         List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
         for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
             UndetVar v = (UndetVar) l.head;
@@ -260,8 +273,7 @@
         List<Type> targs = Type.map(undetvars, getInstFun);
         targs = types.subst(targs, that.tvars, targs);
         checkWithinBounds(that.tvars, targs, warn);
-
-        return getInstFun.apply(qtype1);
+        return that.inst(targs, types);
     }
 
     /** Instantiate method type `mt' by finding instantiations of
@@ -269,36 +281,42 @@
      */
     public Type instantiateMethod(List<Type> tvars,
                                   MethodType mt,
-                                  List<Type> argtypes,
-                                  boolean allowBoxing,
-                                  boolean useVarargs,
-                                  Warner warn) throws NoInstanceException {
+                                  final List<Type> argtypes,
+                                  final boolean allowBoxing,
+                                  final boolean useVarargs,
+                                  final Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
         List<Type> undetvars = Type.map(tvars, fromTypeVarFun);
         List<Type> formals = mt.argtypes;
-
+        //need to capture exactly once - otherwise subsequent
+        //applicability checks might fail
+        final List<Type> capturedArgs = types.capture(argtypes);
+        List<Type> actuals = capturedArgs;
+        List<Type> actualsNoCapture = argtypes;
         // instantiate all polymorphic argument types and
         // set up lower bounds constraints for undetvars
         Type varargsFormal = useVarargs ? formals.last() : null;
-        while (argtypes.nonEmpty() && formals.head != varargsFormal) {
-            Type ft = formals.head;
-            Type at = argtypes.head.baseType();
-            if (at.tag == FORALL)
-                at = instantiateArg((ForAll) at, ft, tvars, warn);
-            Type sft = types.subst(ft, tvars, undetvars);
+        while (actuals.nonEmpty() && formals.head != varargsFormal) {
+            Type formal = formals.head;
+            Type actual = actuals.head.baseType();
+            Type actualNoCapture = actualsNoCapture.head.baseType();
+            if (actual.tag == FORALL)
+                actual = instantiateArg((ForAll)actual, formal, tvars, warn);
+            Type undetFormal = types.subst(formal, tvars, undetvars);
             boolean works = allowBoxing
-                ? types.isConvertible(at, sft, warn)
-                : types.isSubtypeUnchecked(at, sft, warn);
+                ? types.isConvertible(actual, undetFormal, warn)
+                : types.isSubtypeUnchecked(actual, undetFormal, warn);
             if (!works) {
                 throw unambiguousNoInstanceException
                     .setMessage("no.conforming.assignment.exists",
-                                tvars, at, ft);
+                                tvars, actualNoCapture, formal);
             }
             formals = formals.tail;
-            argtypes = argtypes.tail;
+            actuals = actuals.tail;
+            actualsNoCapture = actualsNoCapture.tail;
         }
         if (formals.head != varargsFormal || // not enough args
-            !useVarargs && argtypes.nonEmpty()) { // too many args
+            !useVarargs && actuals.nonEmpty()) { // too many args
             // argument lists differ in length
             throw unambiguousNoInstanceException
                 .setMessage("arg.length.mismatch");
@@ -306,20 +324,21 @@
 
         // for varargs arguments as well
         if (useVarargs) {
-            Type elt = types.elemtype(varargsFormal);
-            Type sft = types.subst(elt, tvars, undetvars);
-            while (argtypes.nonEmpty()) {
-                Type ft = sft;
-                Type at = argtypes.head.baseType();
-                if (at.tag == FORALL)
-                    at = instantiateArg((ForAll) at, ft, tvars, warn);
-                boolean works = types.isConvertible(at, sft, warn);
+            Type elemType = types.elemtype(varargsFormal);
+            Type elemUndet = types.subst(elemType, tvars, undetvars);
+            while (actuals.nonEmpty()) {
+                Type actual = actuals.head.baseType();
+                Type actualNoCapture = actualsNoCapture.head.baseType();
+                if (actual.tag == FORALL)
+                    actual = instantiateArg((ForAll)actual, elemType, tvars, warn);
+                boolean works = types.isConvertible(actual, elemUndet, warn);
                 if (!works) {
                     throw unambiguousNoInstanceException
                         .setMessage("no.conforming.assignment.exists",
-                                    tvars, at, ft);
+                                    tvars, actualNoCapture, elemType);
                 }
-                argtypes = argtypes.tail;
+                actuals = actuals.tail;
+                actualsNoCapture = actualsNoCapture.tail;
             }
         }
 
@@ -350,16 +369,38 @@
         }
         checkWithinBounds(tvars, undettypes.toList(), warn);
 
+        mt = (MethodType)types.subst(mt, tvars, insttypes.toList());
+
         if (!restvars.isEmpty()) {
             // if there are uninstantiated variables,
             // quantify result type with them
-            mt = new MethodType(mt.argtypes,
-                                new ForAll(restvars.toList(), mt.restype),
-                                mt.thrown, syms.methodClass);
+            final List<Type> inferredTypes = insttypes.toList();
+            final List<Type> all_tvars = tvars; //this is the wrong tvars
+            final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass);
+            mt2.restype = new ForAll(restvars.toList(), mt.restype) {
+                @Override
+                public Type inst(List<Type> inferred, Types types) throws NoInstanceException {
+                    List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
+                   if (!rs.argumentsAcceptable(capturedArgs, formals,
+                           allowBoxing, useVarargs, warn)) {
+                      // inferred method is not applicable
+                      throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes);
+                   }
+                   // check that inferred bounds conform to their bounds
+                   checkWithinBounds(all_tvars,
+                           types.subst(inferredTypes, tvars, inferred), warn);
+                   return super.inst(inferred, types);
+            }};
+            return mt2;
         }
-
-        // return instantiated version of method type
-        return types.subst(mt, tvars, insttypes.toList());
+        else if (!rs.argumentsAcceptable(capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) {
+            // inferred method is not applicable
+            throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", mt.getParameterTypes(), argtypes);
+        }
+        else {
+            // return instantiated version of method type
+            return mt;
+        }
     }
     //where
 
@@ -371,7 +412,7 @@
         private Type instantiateArg(ForAll that,
                                     Type to,
                                     List<Type> tvars,
-                                    Warner warn) throws NoInstanceException {
+                                    Warner warn) throws InferenceException {
             List<Type> targs;
             try {
                 return instantiateExpr(that, to, warn);
@@ -388,16 +429,16 @@
     private void checkWithinBounds(List<Type> tvars,
                                    List<Type> arguments,
                                    Warner warn)
-        throws NoInstanceException {
+        throws InvalidInstanceException {
         for (List<Type> tvs = tvars, args = arguments;
              tvs.nonEmpty();
              tvs = tvs.tail, args = args.tail) {
             if (args.head instanceof UndetVar) continue;
             List<Type> bounds = types.subst(types.getBounds((TypeVar)tvs.head), tvars, arguments);
             if (!types.isSubtypeUnchecked(args.head, bounds, warn))
-                throw unambiguousNoInstanceException
+                throw invalidInstanceException
                     .setMessage("inferred.do.not.conform.to.bounds",
-                                arguments, tvars);
+                                args.head, bounds);
         }
     }
 }
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jun 26 10:26:27 2009 -0700
@@ -82,15 +82,15 @@
         syms = Symtab.instance(context);
 
         varNotFound = new
-            ResolveError(ABSENT_VAR, syms.errSymbol, "variable not found");
+            SymbolNotFoundError(ABSENT_VAR);
         wrongMethod = new
-            ResolveError(WRONG_MTH, syms.errSymbol, "method not found");
+            InapplicableSymbolError(syms.errSymbol);
         wrongMethods = new
-            ResolveError(WRONG_MTHS, syms.errSymbol, "wrong methods");
+            InapplicableSymbolsError(syms.errSymbol);
         methodNotFound = new
-            ResolveError(ABSENT_MTH, syms.errSymbol, "method not found");
+            SymbolNotFoundError(ABSENT_MTH);
         typeNotFound = new
-            ResolveError(ABSENT_TYP, syms.errSymbol, "type not found");
+            SymbolNotFoundError(ABSENT_TYP);
 
         names = Names.instance(context);
         log = Log.instance(context);
@@ -110,11 +110,11 @@
 
     /** error symbols, which are returned when resolution fails
      */
-    final ResolveError varNotFound;
-    final ResolveError wrongMethod;
-    final ResolveError wrongMethods;
-    final ResolveError methodNotFound;
-    final ResolveError typeNotFound;
+    final SymbolNotFoundError varNotFound;
+    final InapplicableSymbolError wrongMethod;
+    final InapplicableSymbolsError wrongMethods;
+    final SymbolNotFoundError methodNotFound;
+    final SymbolNotFoundError typeNotFound;
 
 /* ************************************************************************
  * Identifier resolution
@@ -299,7 +299,7 @@
                         boolean allowBoxing,
                         boolean useVarargs,
                         Warner warn)
-        throws Infer.NoInstanceException {
+        throws Infer.InferenceException {
         if (useVarargs && (m.flags() & VARARGS) == 0) return null;
         Type mt = types.memberType(site, m);
 
@@ -370,7 +370,7 @@
         try {
             return rawInstantiate(env, site, m, argtypes, typeargtypes,
                                   allowBoxing, useVarargs, warn);
-        } catch (Infer.NoInstanceException ex) {
+        } catch (Infer.InferenceException ex) {
             return null;
         }
     }
@@ -584,7 +584,7 @@
                 default: return bestSoFar;
                 }
             }
-        } catch (Infer.NoInstanceException ex) {
+        } catch (Infer.InferenceException ex) {
             switch (bestSoFar.kind) {
             case ABSENT_MTH:
                 return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
@@ -710,13 +710,13 @@
             return new AmbiguityError(m1, m2);
         case AMBIGUOUS:
             AmbiguityError e = (AmbiguityError)m2;
-            Symbol err1 = mostSpecific(m1, e.sym1, env, site, allowBoxing, useVarargs);
+            Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
             Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
             if (err1 == err2) return err1;
-            if (err1 == e.sym1 && err2 == e.sym2) return m2;
+            if (err1 == e.sym && err2 == e.sym2) return m2;
             if (err1 instanceof AmbiguityError &&
                 err2 instanceof AmbiguityError &&
-                ((AmbiguityError)err1).sym1 == ((AmbiguityError)err2).sym1)
+                ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
                 return new AmbiguityError(m1, m2);
             else
                 return new AmbiguityError(err1, err2);
@@ -1192,18 +1192,12 @@
                   List<Type> argtypes,
                   List<Type> typeargtypes) {
         if (sym.kind >= AMBIGUOUS) {
-//          printscopes(site.tsym.members());//DEBUG
+            ResolveError errSym = (ResolveError)sym;
             if (!site.isErroneous() &&
                 !Type.isErroneous(argtypes) &&
                 (typeargtypes==null || !Type.isErroneous(typeargtypes)))
-                ((ResolveError)sym).report(log, pos, site, name, argtypes, typeargtypes);
-            do {
-                sym = ((ResolveError)sym).sym;
-            } while (sym.kind >= AMBIGUOUS);
-            if (sym == syms.errSymbol // preserve the symbol name through errors
-                || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned
-                    && (sym.kind & TYP) != 0))
-                sym = types.createErrorType(name, qualified ? site.tsym : syms.noSymbol, sym.type).tsym;
+                logResolveError(errSym, pos, site, name, argtypes, typeargtypes);
+            sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
         }
         return sym;
     }
@@ -1583,7 +1577,19 @@
 
     public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) {
         AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym);
-        error.report(log, tree.pos(), type.getEnclosingType(), null, null, null);
+        logResolveError(error, tree.pos(), type.getEnclosingType(), null, null, null);
+    }
+    //where
+    private void logResolveError(ResolveError error,
+            DiagnosticPosition pos,
+            Type site,
+            Name name,
+            List<Type> argtypes,
+            List<Type> typeargtypes) {
+        JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
+                pos, site, name, argtypes, typeargtypes);
+        if (d != null)
+            log.report(d);
     }
 
     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
@@ -1592,152 +1598,71 @@
         return argtypes.isEmpty() ? noArgs : argtypes;
     }
 
-    /** Root class for resolve errors.
-     *  Instances of this class indicate "Symbol not found".
-     *  Instances of subclass indicate other errors.
+    /**
+     * Root class for resolution errors. Subclass of ResolveError
+     * represent a different kinds of resolution error - as such they must
+     * specify how they map into concrete compiler diagnostics.
      */
-    private class ResolveError extends Symbol {
+    private abstract class ResolveError extends Symbol {
 
-        ResolveError(int kind, Symbol sym, String debugName) {
+        /** The name of the kind of error, for debugging only. */
+        final String debugName;
+
+        ResolveError(int kind, String debugName) {
             super(kind, 0, null, null, null);
             this.debugName = debugName;
-            this.sym = sym;
         }
 
-        /** The name of the kind of error, for debugging only.
-         */
-        final String debugName;
-
-        /** The symbol that was determined by resolution, or errSymbol if none
-         *  was found.
-         */
-        final Symbol sym;
-
-        /** The symbol that was a close mismatch, or null if none was found.
-         *  wrongSym is currently set if a simgle method with the correct name, but
-         *  the wrong parameters was found.
-         */
-        Symbol wrongSym;
-
-        /** An auxiliary explanation set in case of instantiation errors.
-         */
-        JCDiagnostic explanation;
-
-
+        @Override
         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
             throw new AssertionError();
         }
 
-        /** Print the (debug only) name of the kind of error.
-         */
+        @Override
         public String toString() {
-            return debugName + " wrongSym=" + wrongSym + " explanation=" + explanation;
+            return debugName;
         }
 
-        /** Update wrongSym and explanation and return this.
-         */
-        ResolveError setWrongSym(Symbol sym, JCDiagnostic explanation) {
-            this.wrongSym = sym;
-            this.explanation = explanation;
-            return this;
+        @Override
+        public boolean exists() {
+            return false;
         }
 
-        /** Update wrongSym and return this.
+        /**
+         * Create an external representation for this erroneous symbol to be
+         * used during attribution - by default this returns the symbol of a
+         * brand new error type which stores the original type found
+         * during resolution.
+         *
+         * @param name     the name used during resolution
+         * @param location the location from which the symbol is accessed
          */
-        ResolveError setWrongSym(Symbol sym) {
-            this.wrongSym = sym;
-            this.explanation = null;
-            return this;
+        protected Symbol access(Name name, TypeSymbol location) {
+            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
         }
 
-        public boolean exists() {
-            switch (kind) {
-            case HIDDEN:
-            case ABSENT_VAR:
-            case ABSENT_MTH:
-            case ABSENT_TYP:
-                return false;
-            default:
-                return true;
-            }
-        }
+        /**
+         * Create a diagnostic representing this resolution error.
+         *
+         * @param dkind     The kind of the diagnostic to be created (e.g error).
+         * @param pos       The position to be used for error reporting.
+         * @param site      The original type from where the selection took place.
+         * @param name      The name of the symbol to be resolved.
+         * @param argtypes  The invocation's value arguments,
+         *                  if we looked for a method.
+         * @param typeargtypes  The invocation's type arguments,
+         *                      if we looked for a method.
+         */
+        abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                DiagnosticPosition pos,
+                Type site,
+                Name name,
+                List<Type> argtypes,
+                List<Type> typeargtypes);
 
-        /** Report error.
-         *  @param log       The error log to be used for error reporting.
-         *  @param pos       The position to be used for error reporting.
-         *  @param site      The original type from where the selection took place.
-         *  @param name      The name of the symbol to be resolved.
-         *  @param argtypes  The invocation's value arguments,
-         *                   if we looked for a method.
-         *  @param typeargtypes  The invocation's type arguments,
-         *                   if we looked for a method.
-         */
-        void report(Log log, DiagnosticPosition pos, Type site, Name name,
-                    List<Type> argtypes, List<Type> typeargtypes) {
-            if (argtypes == null)
-                argtypes = List.nil();
-            if (typeargtypes == null)
-                typeargtypes = List.nil();
-            if (name != names.error) {
-                KindName kindname = absentKind(kind);
-                Name idname = name;
-                if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) {
-                    if (isOperator(name)) {
-                        log.error(pos, "operator.cant.be.applied",
-                                  name, argtypes);
-                        return;
-                    }
-                    if (name == names.init) {
-                        kindname = KindName.CONSTRUCTOR;
-                        idname = site.tsym.name;
-                    }
-                }
-                if (kind == WRONG_MTH) {
-                    Symbol ws = wrongSym.asMemberOf(site, types);
-                    log.error(pos,
-                              "cant.apply.symbol" + (explanation != null ? ".1" : ""),
-                              kindname,
-                              ws.name == names.init ? ws.owner.name : ws.name,
-                              methodArguments(ws.type.getParameterTypes()),
-                              methodArguments(argtypes),
-                              kindName(ws.owner),
-                              ws.owner.type,
-                              explanation);
-                } else if (!site.tsym.name.isEmpty()) {
-                    if (site.tsym.kind == PCK && !site.tsym.exists())
-                        log.error(pos, "doesnt.exist", site.tsym);
-                    else {
-                        String errKey = getErrorKey("cant.resolve.location",
-                                                    argtypes, typeargtypes,
-                                                    kindname);
-                        log.error(pos, errKey, kindname, idname, //symbol kindname, name
-                                  typeargtypes, argtypes, //type parameters and arguments (if any)
-                                  typeKindName(site), site); //location kindname, type
-                    }
-                } else {
-                    String errKey = getErrorKey("cant.resolve",
-                                                argtypes, typeargtypes,
-                                                kindname);
-                    log.error(pos, errKey, kindname, idname, //symbol kindname, name
-                              typeargtypes, argtypes); //type parameters and arguments (if any)
-                }
-            }
-        }
-        //where
-        String getErrorKey(String key, List<Type> argtypes, List<Type> typeargtypes, KindName kindname) {
-            String suffix = "";
-            switch (kindname) {
-                case METHOD:
-                case CONSTRUCTOR: {
-                    suffix += ".args";
-                    suffix += typeargtypes.nonEmpty() ? ".params" : "";
-                }
-            }
-            return key + suffix;
-        }
-
-        /** A name designates an operator if it consists
-         *  of a non-empty sequence of operator symbols +-~!/*%&|^<>=
+        /**
+         * A name designates an operator if it consists
+         * of a non-empty sequence of operator symbols +-~!/*%&|^<>=
          */
         boolean isOperator(Name name) {
             int i = 0;
@@ -1747,9 +1672,206 @@
         }
     }
 
-    /** Resolve error class indicating that a symbol is not accessible.
+    /**
+     * This class is the root class of all resolution errors caused by
+     * an invalid symbol being found during resolution.
      */
-    class AccessError extends ResolveError {
+    abstract class InvalidSymbolError extends ResolveError {
+
+        /** The invalid symbol found during resolution */
+        Symbol sym;
+
+        InvalidSymbolError(int kind, Symbol sym, String debugName) {
+            super(kind, debugName);
+            this.sym = sym;
+        }
+
+        @Override
+        public boolean exists() {
+            return true;
+        }
+
+        @Override
+        public String toString() {
+             return super.toString() + " wrongSym=" + sym;
+        }
+
+        @Override
+        public Symbol access(Name name, TypeSymbol location) {
+            if (sym.kind >= AMBIGUOUS)
+                return ((ResolveError)sym).access(name, location);
+            else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
+                return types.createErrorType(name, location, sym.type).tsym;
+            else
+                return sym;
+        }
+    }
+
+    /**
+     * InvalidSymbolError error class indicating that a symbol matching a
+     * given name does not exists in a given site.
+     */
+    class SymbolNotFoundError extends ResolveError {
+
+        SymbolNotFoundError(int kind) {
+            super(kind, "symbol not found error");
+        }
+
+        @Override
+        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                DiagnosticPosition pos,
+                Type site,
+                Name name,
+                List<Type> argtypes,
+                List<Type> typeargtypes) {
+            argtypes = argtypes == null ? List.<Type>nil() : argtypes;
+            typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
+            if (name == names.error)
+                return null;
+
+            if (isOperator(name)) {
+                return diags.create(dkind, false, log.currentSource(), pos,
+                        "operator.cant.be.applied", name, argtypes);
+            }
+            boolean hasLocation = false;
+            if (!site.tsym.name.isEmpty()) {
+                if (site.tsym.kind == PCK && !site.tsym.exists()) {
+                    return diags.create(dkind, false, log.currentSource(), pos,
+                        "doesnt.exist", site.tsym);
+                }
+                hasLocation = true;
+            }
+            boolean isConstructor = kind == ABSENT_MTH &&
+                    name == names.table.names.init;
+            KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
+            Name idname = isConstructor ? site.tsym.name : name;
+            String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
+            if (hasLocation) {
+                return diags.create(dkind, false, log.currentSource(), pos,
+                        errKey, kindname, idname, //symbol kindname, name
+                        typeargtypes, argtypes, //type parameters and arguments (if any)
+                        typeKindName(site), site); //location kindname, type
+            }
+            else {
+                return diags.create(dkind, false, log.currentSource(), pos,
+                        errKey, kindname, idname, //symbol kindname, name
+                        typeargtypes, argtypes); //type parameters and arguments (if any)
+            }
+        }
+        //where
+        private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
+            String key = "cant.resolve";
+            String suffix = hasLocation ? ".location" : "";
+            switch (kindname) {
+                case METHOD:
+                case CONSTRUCTOR: {
+                    suffix += ".args";
+                    suffix += hasTypeArgs ? ".params" : "";
+                }
+            }
+            return key + suffix;
+        }
+    }
+
+    /**
+     * InvalidSymbolError error class indicating that a given symbol
+     * (either a method, a constructor or an operand) is not applicable
+     * given an actual arguments/type argument list.
+     */
+    class InapplicableSymbolError extends InvalidSymbolError {
+
+        /** An auxiliary explanation set in case of instantiation errors. */
+        JCDiagnostic explanation;
+
+        InapplicableSymbolError(Symbol sym) {
+            super(WRONG_MTH, sym, "inapplicable symbol error");
+        }
+
+        /** Update sym and explanation and return this.
+         */
+        InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) {
+            this.sym = sym;
+            this.explanation = explanation;
+            return this;
+        }
+
+        /** Update sym and return this.
+         */
+        InapplicableSymbolError setWrongSym(Symbol sym) {
+            this.sym = sym;
+            this.explanation = null;
+            return this;
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + " explanation=" + explanation;
+        }
+
+        @Override
+        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                DiagnosticPosition pos,
+                Type site,
+                Name name,
+                List<Type> argtypes,
+                List<Type> typeargtypes) {
+            if (name == names.error)
+                return null;
+
+            if (isOperator(name)) {
+                return diags.create(dkind, false, log.currentSource(),
+                        pos, "operator.cant.be.applied", name, argtypes);
+            }
+            else {
+                Symbol ws = sym.asMemberOf(site, types);
+                return diags.create(dkind, false, log.currentSource(), pos,
+                          "cant.apply.symbol" + (explanation != null ? ".1" : ""),
+                          kindName(ws),
+                          ws.name == names.init ? ws.owner.name : ws.name,
+                          methodArguments(ws.type.getParameterTypes()),
+                          methodArguments(argtypes),
+                          kindName(ws.owner),
+                          ws.owner.type,
+                          explanation);
+            }
+        }
+
+        @Override
+        public Symbol access(Name name, TypeSymbol location) {
+            return types.createErrorType(name, location, syms.errSymbol.type).tsym;
+        }
+    }
+
+    /**
+     * ResolveError error class indicating that a set of symbols
+     * (either methods, constructors or operands) is not applicable
+     * given an actual arguments/type argument list.
+     */
+    class InapplicableSymbolsError extends ResolveError {
+        InapplicableSymbolsError(Symbol sym) {
+            super(WRONG_MTHS, "inapplicable symbols");
+        }
+
+        @Override
+        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                DiagnosticPosition pos,
+                Type site,
+                Name name,
+                List<Type> argtypes,
+                List<Type> typeargtypes) {
+            return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
+                    site, name, argtypes, typeargtypes);
+        }
+    }
+
+    /**
+     * An InvalidSymbolError error class indicating that a symbol is not
+     * accessible from a given site
+     */
+    class AccessError extends InvalidSymbolError {
+
+        private Env<AttrContext> env;
+        private Type site;
 
         AccessError(Symbol sym) {
             this(null, null, sym);
@@ -1763,111 +1885,107 @@
                 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
         }
 
-        private Env<AttrContext> env;
-        private Type site;
+        @Override
+        public boolean exists() {
+            return false;
+        }
 
-        /** Report error.
-         *  @param log       The error log to be used for error reporting.
-         *  @param pos       The position to be used for error reporting.
-         *  @param site      The original type from where the selection took place.
-         *  @param name      The name of the symbol to be resolved.
-         *  @param argtypes  The invocation's value arguments,
-         *                   if we looked for a method.
-         *  @param typeargtypes  The invocation's type arguments,
-         *                   if we looked for a method.
-         */
-        void report(Log log, DiagnosticPosition pos, Type site, Name name,
-                    List<Type> argtypes, List<Type> typeargtypes) {
-            if (sym.owner.type.tag != ERROR) {
-                if (sym.name == names.init && sym.owner != site.tsym)
-                    new ResolveError(ABSENT_MTH, sym.owner, "absent method " + sym).report(
-                        log, pos, site, name, argtypes, typeargtypes);
-                if ((sym.flags() & PUBLIC) != 0
-                    || (env != null && this.site != null
-                        && !isAccessible(env, this.site)))
-                    log.error(pos, "not.def.access.class.intf.cant.access",
-                        sym, sym.location());
-                else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0)
-                    log.error(pos, "report.access", sym,
-                              asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
-                              sym.location());
-                else
-                    log.error(pos, "not.def.public.cant.access",
-                              sym, sym.location());
+        @Override
+        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                DiagnosticPosition pos,
+                Type site,
+                Name name,
+                List<Type> argtypes,
+                List<Type> typeargtypes) {
+            if (sym.owner.type.tag == ERROR)
+                return null;
+
+            if (sym.name == names.init && sym.owner != site.tsym) {
+                return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
+                        pos, site, name, argtypes, typeargtypes);
+            }
+            else if ((sym.flags() & PUBLIC) != 0
+                || (env != null && this.site != null
+                    && !isAccessible(env, this.site))) {
+                return diags.create(dkind, false, log.currentSource(),
+                        pos, "not.def.access.class.intf.cant.access",
+                    sym, sym.location());
+            }
+            else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
+                return diags.create(dkind, false, log.currentSource(),
+                        pos, "report.access", sym,
+                        asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
+                        sym.location());
+            }
+            else {
+                return diags.create(dkind, false, log.currentSource(),
+                        pos, "not.def.public.cant.access", sym, sym.location());
             }
         }
     }
 
-    /** Resolve error class indicating that an instance member was accessed
-     *  from a static context.
+    /**
+     * InvalidSymbolError error class indicating that an instance member
+     * has erroneously been accessed from a static context.
      */
-    class StaticError extends ResolveError {
+    class StaticError extends InvalidSymbolError {
+
         StaticError(Symbol sym) {
             super(STATICERR, sym, "static error");
         }
 
-        /** Report error.
-         *  @param log       The error log to be used for error reporting.
-         *  @param pos       The position to be used for error reporting.
-         *  @param site      The original type from where the selection took place.
-         *  @param name      The name of the symbol to be resolved.
-         *  @param argtypes  The invocation's value arguments,
-         *                   if we looked for a method.
-         *  @param typeargtypes  The invocation's type arguments,
-         *                   if we looked for a method.
-         */
-        void report(Log log,
-                    DiagnosticPosition pos,
-                    Type site,
-                    Name name,
-                    List<Type> argtypes,
-                    List<Type> typeargtypes) {
+        @Override
+        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                DiagnosticPosition pos,
+                Type site,
+                Name name,
+                List<Type> argtypes,
+                List<Type> typeargtypes) {
             Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
                 ? types.erasure(sym.type).tsym
                 : sym);
-            log.error(pos, "non-static.cant.be.ref",
-                      kindName(sym), errSym);
+            return diags.create(dkind, false, log.currentSource(), pos,
+                    "non-static.cant.be.ref", kindName(sym), errSym);
         }
     }
 
-    /** Resolve error class indicating an ambiguous reference.
+    /**
+     * InvalidSymbolError error class indicating that a pair of symbols
+     * (either methods, constructors or operands) are ambiguous
+     * given an actual arguments/type argument list.
      */
-    class AmbiguityError extends ResolveError {
-        Symbol sym1;
+    class AmbiguityError extends InvalidSymbolError {
+
+        /** The other maximally specific symbol */
         Symbol sym2;
 
         AmbiguityError(Symbol sym1, Symbol sym2) {
             super(AMBIGUOUS, sym1, "ambiguity error");
-            this.sym1 = sym1;
             this.sym2 = sym2;
         }
 
-        /** Report error.
-         *  @param log       The error log to be used for error reporting.
-         *  @param pos       The position to be used for error reporting.
-         *  @param site      The original type from where the selection took place.
-         *  @param name      The name of the symbol to be resolved.
-         *  @param argtypes  The invocation's value arguments,
-         *                   if we looked for a method.
-         *  @param typeargtypes  The invocation's type arguments,
-         *                   if we looked for a method.
-         */
-        void report(Log log, DiagnosticPosition pos, Type site, Name name,
-                    List<Type> argtypes, List<Type> typeargtypes) {
+        @Override
+        JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
+                DiagnosticPosition pos,
+                Type site,
+                Name name,
+                List<Type> argtypes,
+                List<Type> typeargtypes) {
             AmbiguityError pair = this;
             while (true) {
-                if (pair.sym1.kind == AMBIGUOUS)
-                    pair = (AmbiguityError)pair.sym1;
+                if (pair.sym.kind == AMBIGUOUS)
+                    pair = (AmbiguityError)pair.sym;
                 else if (pair.sym2.kind == AMBIGUOUS)
                     pair = (AmbiguityError)pair.sym2;
                 else break;
             }
-            Name sname = pair.sym1.name;
-            if (sname == names.init) sname = pair.sym1.owner.name;
-            log.error(pos, "ref.ambiguous", sname,
-                      kindName(pair.sym1),
-                      pair.sym1,
-                      pair.sym1.location(site, types),
+            Name sname = pair.sym.name;
+            if (sname == names.init) sname = pair.sym.owner.name;
+            return diags.create(dkind, false, log.currentSource(),
+                      pos, "ref.ambiguous", sname,
+                      kindName(pair.sym),
+                      pair.sym,
+                      pair.sym.location(site, types),
                       kindName(pair.sym2),
                       pair.sym2,
                       pair.sym2.location(site, types));
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Jun 26 10:26:27 2009 -0700
@@ -1521,9 +1521,9 @@
         int acount = 0;
 
         boolean sigReq =
-            typarams.length() != 0 || supertype.getTypeArguments().length() != 0;
+            typarams.length() != 0 || supertype.allparams().length() != 0;
         for (List<Type> l = interfaces; !sigReq && l.nonEmpty(); l = l.tail)
-            sigReq = l.head.getTypeArguments().length() != 0;
+            sigReq = l.head.allparams().length() != 0;
         if (sigReq) {
             assert source.allowGenerics();
             int alenIdx = writeAttr(names.Signature);
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jun 26 10:26:27 2009 -0700
@@ -84,7 +84,7 @@
     {0} {1} in {4} {5} cannot be applied to given types\n\
     required: {2}\n\
     found: {3}
- compiler.err.cant.apply.symbol.1=\
+compiler.err.cant.apply.symbol.1=\
     {0} {1} in {4} {5} cannot be applied to given types;\n\
     required: {2}\n\
     found: {3}\n\
@@ -469,6 +469,8 @@
     type parameters of {0} cannot be determined
 compiler.err.undetermined.type.1=\
     type parameters of {0} cannot be determined; {1}
+compiler.err.invalid.inferred.types=\
+    invalid inferred types for {0}; {1}
 compiler.err.unreachable.stmt=\
     unreachable statement
 compiler.err.initializer.must.be.able.to.complete.normally=\
@@ -995,7 +997,13 @@
 compiler.misc.arg.length.mismatch=\
     cannot instantiate from arguments because actual and formal argument lists differ in length
 compiler.misc.inferred.do.not.conform.to.bounds=\
-    inferred type argument(s) {0} do not conform to bounds of type variable(s) {1}
+    inferred type does not conform to declared bound(s)\n\
+    inferred: {0}\n\
+    bound(s): {1}
+compiler.misc.inferred.do.not.conform.to.params=\
+    actual arguments do not conforms to inferred formal arguments\n\
+    required: {0}\n\
+    found: {1}
 
 #####
 
--- a/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java	Fri Jun 26 10:26:27 2009 -0700
@@ -109,7 +109,7 @@
         return formatDiagnostic(d, locale);
     }
 
-    abstract String formatDiagnostic(JCDiagnostic d, Locale locale);
+    protected abstract String formatDiagnostic(JCDiagnostic d, Locale locale);
 
     public String formatPosition(JCDiagnostic d, PositionKind pk,Locale l) {
         assert (d.getPosition() != Position.NOPOS);
@@ -172,9 +172,6 @@
             return formatIterable(d, (Iterable<?>)arg, l);
         }
         else if (arg instanceof Type) {
-            if (!allCaptured.contains(arg)) {
-                allCaptured = allCaptured.append((Type)arg);
-            }
             return printer.visit((Type)arg, l);
         }
         else if (arg instanceof Symbol) {
@@ -482,5 +479,12 @@
         protected String capturedVarId(CapturedType t, Locale locale) {
             return "" + (allCaptured.indexOf(t) + 1);
         }
+        @Override
+        public String visitCapturedType(CapturedType t, Locale locale) {
+            if (!allCaptured.contains(t)) {
+                allCaptured = allCaptured.append(t);
+            }
+            return super.visitCapturedType(t, locale);
+        }
     };
 }
--- a/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Fri Jun 26 10:26:27 2009 -0700
@@ -58,7 +58,7 @@
 
     protected DiagnosticSource getSource(JavaFileObject file) {
         if (file == null)
-            return null;
+            return DiagnosticSource.NO_SOURCE;
         DiagnosticSource s = sourceMap.get(file);
         if (s == null) {
             s = new DiagnosticSource(file, this);
--- a/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java	Fri Jun 26 10:26:27 2009 -0700
@@ -46,11 +46,22 @@
  *  deletion without notice.</b>
  */
 public class DiagnosticSource {
+
+    /* constant DiagnosticSource to be used when sourcefile is missing */
+    public static final DiagnosticSource NO_SOURCE = new DiagnosticSource() {
+        @Override
+        protected boolean findLine(int pos) {
+            return false;
+        }
+    };
+
     public DiagnosticSource(JavaFileObject fo, AbstractLog log) {
         this.fileObject = fo;
         this.log = log;
     }
 
+    private DiagnosticSource() {}
+
     /** Return the underlying file object handled by this
      *  DiagnosticSource object.
      */
@@ -134,7 +145,7 @@
     /** Find the line in the buffer that contains the current position
      * @param pos      Character offset into the buffer
      */
-    private boolean findLine(int pos) {
+    protected boolean findLine(int pos) {
         if (pos == Position.NOPOS)
             return false;
 
--- a/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Fri Jun 26 10:26:27 2009 -0700
@@ -83,7 +83,7 @@
          */
         public JCDiagnostic error(
                 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
-            return new JCDiagnostic(formatter, ERROR, true, source, pos, qualify(ERROR, key), args);
+            return create(ERROR, true, source, pos, key, args);
         }
 
         /**
@@ -96,7 +96,7 @@
          */
         public JCDiagnostic mandatoryWarning(
                  DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
-            return new JCDiagnostic(formatter, WARNING, true, source, pos, qualify(WARNING, key), args);
+            return create(WARNING, true, source, pos, key, args);
         }
 
         /**
@@ -108,7 +108,7 @@
          */
         public JCDiagnostic warning(
                 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
-            return new JCDiagnostic(formatter, WARNING, false, source, pos, qualify(WARNING, key), args);
+            return create(WARNING, false, source, pos, key, args);
         }
 
         /**
@@ -118,7 +118,7 @@
          *  @see MandatoryWarningHandler
          */
         public JCDiagnostic mandatoryNote(DiagnosticSource source, String key, Object... args) {
-            return new JCDiagnostic(formatter, NOTE, true, source, null, qualify(NOTE, key), args);
+            return create(NOTE, true, source, null, key, args);
         }
 
         /**
@@ -127,7 +127,7 @@
          *  @param args   Fields of the error message.
          */
         public JCDiagnostic note(String key, Object... args) {
-            return note(null, null, key, args);
+            return create(NOTE, false, null, null, key, args);
         }
 
         /**
@@ -139,7 +139,7 @@
          */
         public JCDiagnostic note(
                 DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
-            return new JCDiagnostic(formatter, NOTE, false, source, pos, qualify(NOTE, key), args);
+            return create(NOTE, false, source, pos, key, args);
         }
 
         /**
@@ -148,7 +148,21 @@
          *  @param args   Fields of the error message.
          */
         public JCDiagnostic fragment(String key, Object... args) {
-            return new JCDiagnostic(formatter, FRAGMENT, false, null, null, qualify(FRAGMENT, key), args);
+            return create(FRAGMENT, false, null, null, key, args);
+        }
+
+        /**
+         * Create a new diagnostic of the given kind.
+         *  @param kind        The diagnostic kind
+         *  @param isMandatory is diagnostic mandatory?
+         *  @param source      The source of the compilation unit, if any, in which to report the note.
+         *  @param pos         The source position at which to report the note.
+         *  @param key         The key for the localized error message.
+         *  @param args        Fields of the error message.
+         */
+        public JCDiagnostic create(
+                DiagnosticType kind, boolean isMandatory, DiagnosticSource source, DiagnosticPosition pos, String key, Object... args) {
+            return new JCDiagnostic(formatter, kind, isMandatory, source, pos, qualify(kind, key), args);
         }
 
         protected String qualify(DiagnosticType t, String key) {
--- a/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java	Fri Jun 26 10:26:27 2009 -0700
@@ -68,7 +68,10 @@
     final JavacMessages messages;
 
     /* name simplifier used by this formatter */
-    ClassNameSimplifier nameSimplifier;
+    protected ClassNameSimplifier nameSimplifier;
+
+    /* type/symbol printer used by this formatter */
+    private RichPrinter printer;
 
     /* map for keeping track of a where clause associated to a given type */
     Map<WhereClauseKind, Map<Type, JCDiagnostic>> whereClauses;
@@ -83,7 +86,7 @@
 
     protected RichDiagnosticFormatter(Context context) {
         super((AbstractDiagnosticFormatter)Log.instance(context).getDiagnosticFormatter());
-        this.formatter.setPrinter(printer);
+        setRichPrinter(new RichPrinter());
         this.syms = Symtab.instance(context);
         this.diags = JCDiagnostic.Factory.instance(context);
         this.types = Types.instance(context);
@@ -117,6 +120,23 @@
     }
 
     /**
+     * Sets the type/symbol printer used by this formatter.
+     * @param printer the rich printer to be set
+     */
+    protected void setRichPrinter(RichPrinter printer) {
+        this.printer = printer;
+        formatter.setPrinter(printer);
+    }
+
+    /**
+     * Gets the type/symbol printer used by this formatter.
+     * @return type/symbol rich printer
+     */
+    protected RichPrinter getRichPrinter() {
+        return printer;
+    }
+
+    /**
      * Preprocess a given diagnostic by looking both into its arguments and into
      * its subdiagnostics (if any). This preprocessing is responsible for
      * generating info corresponding to features like where clauses, name
@@ -217,7 +237,7 @@
      * name belong to different packages - in this case the formatter reverts
      * to fullnames as compact names might lead to a confusing diagnostic.
      */
-    class ClassNameSimplifier {
+    protected class ClassNameSimplifier {
 
         /* table for keeping track of all short name usages */
         Map<Name, List<Symbol>> nameClashes = new HashMap<Name, List<Symbol>>();
@@ -272,7 +292,7 @@
      * discovered during type/symbol preprocessing. This printer is set on the delegate
      * formatter so that rich type/symbol info can be properly rendered.
      */
-    protected Printer printer = new Printer() {
+    protected class RichPrinter extends Printer {
 
         @Override
         public String localize(Locale locale, String key, Object... args) {
--- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Fri Jun 26 10:26:27 2009 -0700
@@ -74,7 +74,7 @@
 public class AttributeWriter extends BasicWriter
         implements Attribute.Visitor<Void,Void>
 {
-    static AttributeWriter instance(Context context) {
+    public static AttributeWriter instance(Context context) {
         AttributeWriter instance = context.get(AttributeWriter.class);
         if (instance == null)
             instance = new AttributeWriter(context);
--- a/src/share/classes/com/sun/tools/javap/ClassWriter.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/ClassWriter.java	Fri Jun 26 10:26:27 2009 -0700
@@ -93,17 +93,25 @@
         this.lastModified = lastModified;
     }
 
-    ClassFile getClassFile() {
+    protected ClassFile getClassFile() {
         return classFile;
     }
 
-    Method getMethod() {
+    protected void setClassFile(ClassFile cf) {
+        classFile = cf;
+        constant_pool = classFile.constant_pool;
+    }
+
+    protected Method getMethod() {
         return method;
     }
 
+    protected void setMethod(Method m) {
+        method = m;
+    }
+
     public void write(ClassFile cf) {
-        classFile = cf;
-        constant_pool = classFile.constant_pool;
+        setClassFile(cf);
 
         if ((options.sysInfo || options.verbose) && !options.compat) {
             if (uri != null) {
@@ -197,13 +205,13 @@
         println();
     }
 
-    void writeFields() {
+    protected void writeFields() {
         for (Field f: classFile.fields) {
             writeField(f);
         }
     }
 
-    void writeField(Field f) {
+    protected void writeField(Field f) {
         if (!options.checkAccess(f.access_flags))
             return;
 
@@ -259,12 +267,12 @@
             println();
     }
 
-    void writeMethods() {
+    protected void writeMethods() {
         for (Method m: classFile.methods)
             writeMethod(m);
     }
 
-    void writeMethod(Method m) {
+    protected void writeMethod(Method m) {
         if (!options.checkAccess(m.access_flags))
             return;
 
--- a/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Fri Jun 26 10:26:27 2009 -0700
@@ -40,7 +40,7 @@
  *  deletion without notice.</b>
  */
 public class ConstantWriter extends BasicWriter {
-    static ConstantWriter instance(Context context) {
+    public static ConstantWriter instance(Context context) {
         ConstantWriter instance = context.get(ConstantWriter.class);
         if (instance == null)
             instance = new ConstantWriter(context);
@@ -54,7 +54,12 @@
         options = Options.instance(context);
     }
 
-    void writeConstantPool() {
+    protected void writeConstantPool() {
+        ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
+        writeConstantPool(constant_pool);
+    }
+
+    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));
@@ -114,7 +119,6 @@
 
         };
         println("  Constant pool:");
-        ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
         int cpx = 1;
         while (cpx < constant_pool.size()) {
             try {
@@ -127,7 +131,7 @@
         }
     }
 
-    void write(int cpx) {
+    protected void write(int cpx) {
         ClassFile classFile = classWriter.getClassFile();
         if (cpx == 0) {
             print("#0");
--- a/src/share/classes/com/sun/tools/javap/JavapTask.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/JavapTask.java	Fri Jun 26 10:26:27 2009 -0700
@@ -36,6 +36,7 @@
 import java.io.Writer;
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -298,21 +299,28 @@
 
     };
 
-    JavapTask() {
+    public JavapTask() {
         context = new Context();
         context.put(Messages.class, this);
         options = Options.instance(context);
+        attributeFactory = new Attribute.Factory();
     }
 
-    JavapTask(Writer out,
+    public JavapTask(Writer out,
+            JavaFileManager fileManager,
+            DiagnosticListener<? super JavaFileObject> diagnosticListener) {
+        this();
+        this.log = getPrintWriterForWriter(out);
+        this.fileManager = fileManager;
+        this.diagnosticListener = diagnosticListener;
+    }
+
+    public JavapTask(Writer out,
             JavaFileManager fileManager,
             DiagnosticListener<? super JavaFileObject> diagnosticListener,
             Iterable<String> options,
             Iterable<String> classes) {
-        this();
-        this.log = getPrintWriterForWriter(out);
-        this.fileManager = fileManager;
-        this.diagnosticListener = diagnosticListener;
+        this(out, fileManager, diagnosticListener);
 
         try {
             handleOptions(options, false);
@@ -553,29 +561,10 @@
                        continue;
                     }
                 }
-                Attribute.Factory attributeFactory = new Attribute.Factory();
                 attributeFactory.setCompat(options.compat);
                 attributeFactory.setJSR277(options.jsr277);
 
-                InputStream in = fo.openInputStream();
-                SizeInputStream sizeIn = null;
-                MessageDigest md  = null;
-                if (options.sysInfo || options.verbose) {
-                    md = MessageDigest.getInstance("MD5");
-                    in = new DigestInputStream(in, md);
-                    in = sizeIn = new SizeInputStream(in);
-                }
-
-                ClassFile cf = ClassFile.read(in, attributeFactory);
-
-                if (options.sysInfo || options.verbose) {
-                    classWriter.setFile(fo.toUri());
-                    classWriter.setLastModified(fo.getLastModified());
-                    classWriter.setDigest("MD5", md.digest());
-                    classWriter.setFileSize(sizeIn.size());
-                }
-
-                classWriter.write(cf);
+                write(read(fo));
 
             } catch (ConstantPoolException e) {
                 diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
@@ -606,6 +595,103 @@
         return ok;
     }
 
+    public static class ClassFileInfo {
+        ClassFileInfo(JavaFileObject fo, ClassFile cf, byte[] digest, int size) {
+            this.fo = fo;
+            this.cf = cf;
+            this.digest = digest;
+            this.size = size;
+        }
+        public final JavaFileObject fo;
+        public final ClassFile cf;
+        public final byte[] digest;
+        public final int size;
+    }
+
+    public ClassFileInfo read(JavaFileObject fo) throws IOException, ConstantPoolException {
+        InputStream in = fo.openInputStream();
+        try {
+            SizeInputStream sizeIn = null;
+            MessageDigest md  = null;
+            if (options.sysInfo || options.verbose) {
+                try {
+                    md = MessageDigest.getInstance("MD5");
+                } catch (NoSuchAlgorithmException ignore) {
+                }
+                in = new DigestInputStream(in, md);
+                in = sizeIn = new SizeInputStream(in);
+            }
+
+            ClassFile cf = ClassFile.read(in, attributeFactory);
+            byte[] digest = (md == null) ? null : md.digest();
+            int size = (sizeIn == null) ? -1 : sizeIn.size();
+            return new ClassFileInfo(fo, cf, digest, size);
+        } finally {
+            in.close();
+        }
+    }
+
+    public void write(ClassFileInfo info) {
+        ClassWriter classWriter = ClassWriter.instance(context);
+        if (options.sysInfo || options.verbose) {
+            classWriter.setFile(info.fo.toUri());
+            classWriter.setLastModified(info.fo.getLastModified());
+            classWriter.setDigest("MD5", info.digest);
+            classWriter.setFileSize(info.size);
+        }
+
+        classWriter.write(info.cf);
+    }
+
+    protected void setClassFile(ClassFile classFile) {
+        ClassWriter classWriter = ClassWriter.instance(context);
+        classWriter.setClassFile(classFile);
+    }
+
+    protected void setMethod(Method enclosingMethod) {
+        ClassWriter classWriter = ClassWriter.instance(context);
+        classWriter.setMethod(enclosingMethod);
+    }
+
+    protected void write(Attribute value) {
+        AttributeWriter attrWriter = AttributeWriter.instance(context);
+        ClassWriter classWriter = ClassWriter.instance(context);
+        ClassFile cf = classWriter.getClassFile();
+        attrWriter.write(cf, value, cf.constant_pool);
+    }
+
+    protected void write(Attributes attrs) {
+        AttributeWriter attrWriter = AttributeWriter.instance(context);
+        ClassWriter classWriter = ClassWriter.instance(context);
+        ClassFile cf = classWriter.getClassFile();
+        attrWriter.write(cf, attrs, cf.constant_pool);
+    }
+
+    protected void write(ConstantPool constant_pool) {
+        ConstantWriter constantWriter = ConstantWriter.instance(context);
+        constantWriter.writeConstantPool(constant_pool);
+    }
+
+    protected void write(ConstantPool constant_pool, int value) {
+        ConstantWriter constantWriter = ConstantWriter.instance(context);
+        constantWriter.write(value);
+    }
+
+    protected void write(ConstantPool.CPInfo value) {
+        ConstantWriter constantWriter = ConstantWriter.instance(context);
+        constantWriter.println(value);
+    }
+
+    protected void write(Field value) {
+        ClassWriter classWriter = ClassWriter.instance(context);
+        classWriter.writeField(value);
+    }
+
+    protected void write(Method value) {
+        ClassWriter classWriter = ClassWriter.instance(context);
+        classWriter.writeMethod(value);
+    }
+
     private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
         return JavapFileManager.create(dl, log, options);
     }
@@ -735,7 +821,7 @@
         }
     }
 
-    Context context;
+    protected Context context;
     JavaFileManager fileManager;
     PrintWriter log;
     DiagnosticListener<? super JavaFileObject> diagnosticListener;
@@ -744,6 +830,7 @@
     //ResourceBundle bundle;
     Locale task_locale;
     Map<Locale, ResourceBundle> bundles;
+    protected Attribute.Factory attributeFactory;
 
     private static final String progname = "javap";
 
--- a/src/share/classes/com/sun/tools/javap/SourceWriter.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/SourceWriter.java	Fri Jun 26 10:26:27 2009 -0700
@@ -134,6 +134,9 @@
     }
 
     private String readSource(ClassFile cf) {
+        if (fileManager == null)
+            return null;
+
         Location location;
         if (fileManager.hasLocation((StandardLocation.SOURCE_PATH)))
             location = StandardLocation.SOURCE_PATH;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6835430/A.java	Fri Jun 26 10:26:27 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.
+ */
+
+class A<T extends A<T>> {
+    class C {
+        public T getT() { return null; }
+    }
+}
+
+class B extends A<B> {
+    public class D extends A<B>.C {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/6835430/T6835430.java	Fri Jun 26 10:26:27 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 6835430
+ * @summary 6835430: javac does not generate signature attributes for classes extending parameterized inner classes
+ * @author mcimadamore
+ *
+ * @compile A.java
+ * @compile T6835430.java
+ */
+
+class T6835430 {
+    void test(B.D d) {
+        B b = d.getT();
+    }
+}
--- a/test/tools/javac/Diagnostics/6799605/T6799605.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/test/tools/javac/Diagnostics/6799605/T6799605.java	Fri Jun 26 10:26:27 2009 -0700
@@ -27,6 +27,7 @@
  * @summary Basic/Raw formatters should use type/symbol printer instead of toString()
  * @author  mcimadamore
  * @compile/fail/ref=T6799605.out -XDrawDiagnostics  T6799605.java
+ * @compile/fail/ref=T6799605.out -XDoldDiags -XDrawDiagnostics  T6799605.java
  */
 
 class T6799605<X> {
--- a/test/tools/javac/Diagnostics/6799605/T6799605.out	Thu Jun 25 12:10:11 2009 -0700
+++ b/test/tools/javac/Diagnostics/6799605/T6799605.out	Fri Jun 26 10:26:27 2009 -0700
@@ -1,4 +1,4 @@
-T6799605.java:39:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>, kindname.class, T6799605<X>
-T6799605.java:40:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>, kindname.class, T6799605<X>
-T6799605.java:41:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>, kindname.class, T6799605<X>
+T6799605.java:40:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>, kindname.class, T6799605<X>
+T6799605.java:41:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>, kindname.class, T6799605<X>
+T6799605.java:42:9: compiler.err.cant.resolve.location.args: kindname.method, m, , T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>, kindname.class, T6799605<X>
 3 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/api/6852595/T6852595.java	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,66 @@
+/*
+ * 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     6852595
+ * @summary Accessing scope using JSR199 API on erroneous tree causes Illegal Argument Exception
+ * @author  mcimadamore
+ */
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.source.tree.*;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.javac.tree.JCTree.*;
+
+import static javax.tools.JavaFileObject.Kind;
+
+public class T6852595 {
+    public static void main(String[] args) throws IOException {
+        JavaFileObject sfo = new SimpleJavaFileObject(URI.create("myfo:/Test.java"),Kind.SOURCE) {
+            public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+                return "class BadName { Object o = j; }";
+            }
+        };
+        List<? extends JavaFileObject> files = Arrays.asList(sfo);
+        JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+        JavacTask ct = (JavacTask)tool.getTask(null, null, null, null, null, files);
+        Iterable<? extends CompilationUnitTree> compUnits = ct.parse();
+        CompilationUnitTree cu = compUnits.iterator().next();
+        ClassTree cdef = (ClassTree)cu.getTypeDecls().get(0);
+        JCVariableDecl vdef = (JCVariableDecl)cdef.getMembers().get(0);
+        TreePath path = TreePath.getPath(cu, vdef.init);
+        Trees.instance(ct).getScope(path);
+    }
+}
--- a/test/tools/javac/generics/inference/6302954/T6476073.java	Thu Jun 25 12:10:11 2009 -0700
+++ b/test/tools/javac/generics/inference/6302954/T6476073.java	Fri Jun 26 10:26:27 2009 -0700
@@ -25,6 +25,7 @@
  * @test
  * @bug     6476073
  * @summary Capture using super wildcard of type variables doesn't work
+ * @ignore awaiting for 6650759 (see bug report for a detailed evaluation)
  * @compile T6476073.java
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712a.java	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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     6638712
+ * @author  mcimadamore
+ * @summary Inference with wildcard types causes selection of inapplicable method
+ * @compile/fail/ref=T6638712a.out -XDrawDiagnostics T6638712a.java
+ */
+
+import java.util.*;
+
+class T6638712a {
+
+    <T> Comparator<T> compound(Iterable<? extends Comparator<? super T>> it) {}
+
+    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/generics/inference/6638712/T6638712a.out	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,2 @@
+T6638712a.java:39: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<?>>)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712b.java	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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     6638712
+ * @author  mcimadamore
+ * @summary Inference with wildcard types causes selection of inapplicable method
+ * @compile/fail/ref=T6638712b.out -XDrawDiagnostics T6638712b.java
+ */
+
+class T6638712b<X> {
+
+    <I extends T6638712b<T>, T> T m(I test) { return null; }
+
+    void test(T6638712b<Integer> x) {
+        String i = m(x);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712b.out	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,2 @@
+T6638712b.java:37:21: compiler.err.invalid.inferred.types: T, (compiler.misc.inferred.do.not.conform.to.bounds: T6638712b<java.lang.Integer>, T6638712b<java.lang.String>)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712c.java	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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     6638712 6707034
+ * @author  mcimadamore
+ * @summary Inference with wildcard types causes selection of inapplicable method
+ * @compile/fail/ref=T6638712c.out -XDrawDiagnostics T6638712c.java
+ */
+
+import java.util.*;
+
+class T6638712c {
+
+    <T> T sort(T[] a, Comparator<? super T> c) { return null; }
+
+    void test(Enum[] e, Comparator<Enum<?>> comp) {
+        sort(e, comp);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712c.out	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,2 @@
+T6638712c.java:39:9: compiler.err.cant.apply.symbol: kindname.method, sort, T[],java.util.Comparator<? super T>, java.lang.Enum[],java.util.Comparator<java.lang.Enum<?>>, kindname.class, T6638712c, null
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712d.java	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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     6638712 6730468
+ * @author  mcimadamore
+ * @summary Inference with wildcard types causes selection of inapplicable method
+ * @compile/fail/ref=T6638712d.out -XDrawDiagnostics T6638712d.java
+ */
+
+import java.util.*;
+
+public class T6638712d {
+
+    <U> U m(U u, List<List<U>> list) { return null; }
+
+    void test(List<List<String>> lls) {
+        m(1, lls);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712d.out	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,2 @@
+T6638712d.java:39:9: compiler.err.cant.apply.symbol: kindname.method, m, U,java.util.List<java.util.List<U>>, int,java.util.List<java.util.List<java.lang.String>>, kindname.class, T6638712d, null
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712e.java	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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     6638712 6795689
+ * @author  mcimadamore
+ * @summary Inference with wildcard types causes selection of inapplicable method
+ * @compile/fail/ref=T6638712e.out -XDrawDiagnostics T6638712e.java
+ */
+
+class T6638712e {
+
+    static class Foo<A, B> {
+        <X> Foo<X, B> m(Foo<? super X, ? extends A> foo) { return null;}
+    }
+
+    static class Test {
+        Foo<Object, String> test(Foo<Boolean, String> foo1, Foo<Boolean, Boolean> foo2) {
+             return foo1.m(foo2);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/6638712/T6638712e.out	Fri Jun 26 10:26:27 2009 -0700
@@ -0,0 +1,2 @@
+T6638712e.java:40:27: compiler.err.invalid.inferred.types: X, (compiler.misc.inferred.do.not.conform.to.params: T6638712e.Foo<? super java.lang.Object,? extends java.lang.Boolean>, T6638712e.Foo<java.lang.Boolean,java.lang.Boolean>)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/inference/T6835428.java	Fri Jun 26 10:26:27 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 6835428
+ * @author mcimadamore
+ * @summary regression: return-type inference rejects valid code
+ * @compile T6835428.java
+ */
+
+class T6835428<T> {
+    interface X<T> {}
+   <T extends Comparable<? super T>> T6835428<X<T>> m() { return null; }
+   <T extends Comparable<? super T>> void test() {
+      T6835428<X<T>> t = m();
+   }
+}