changeset 1882:af8417e590f4 jdk8-b78

Merge
author dholmes
date Sun, 17 Feb 2013 16:44:55 -0500
parents f91144b7da75 a3aa32fe4536
children eff030f02ab2 56dfafbb9e1a 6118072811e5
files src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java src/share/classes/com/sun/tools/javac/code/Flags.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/jvm/ClassReader.java test/tools/javac/lambda/TargetType20.out test/tools/javac/lambda/TargetType50.out
diffstat 185 files changed, 9038 insertions(+), 1073 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Feb 04 18:08:53 2013 -0500
+++ b/.hgtags	Sun Feb 17 16:44:55 2013 -0500
@@ -196,3 +196,6 @@
 6f0986ed9b7e11d6eb06618f27e20b18f19fb797 jdk8-b72
 8d0baee36c7184d55c80354b45704c37d6b7ac79 jdk8-b73
 56c97aff46bb577b8668874154c24115a7e8a3e8 jdk8-b74
+c2e11e2ec4a3682513e566849e5562f31ded8c65 jdk8-b75
+e81839b3233792415daaab051698edc6067f1a16 jdk8-b76
+89c66415168925dffe492356ff893ff248bb5603 jdk8-b77
--- a/make/Makefile-classic	Mon Feb 04 18:08:53 2013 -0500
+++ b/make/Makefile-classic	Sun Feb 17 16:44:55 2013 -0500
@@ -241,6 +241,7 @@
 	javax/annotation/processing \
 	javax/lang/model \
 	javax/tools \
+        jdk/ \
 	com/sun/source \
 	com/sun/tools/javac 
 
--- a/make/build.properties	Mon Feb 04 18:08:53 2013 -0500
+++ b/make/build.properties	Sun Feb 17 16:44:55 2013 -0500
@@ -116,6 +116,7 @@
         javax/annotation/processing/ \
         javax/lang/model/ \
         javax/tools/ \
+        jdk/ \
         com/sun/source/ \
         com/sun/tools/javac/ \
         com/sun/tools/doclint/
--- a/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/classfile/AccessFlags.java	Sun Feb 17 16:44:55 2013 -0500
@@ -56,7 +56,7 @@
     public static final int ACC_SYNTHETIC     = 0x1000; // class, inner, field, method
     public static final int ACC_ANNOTATION    = 0x2000; // class, inner
     public static final int ACC_ENUM          = 0x4000; // class, inner, field
-    public static final int ACC_MODULE        = 0x8000; // class, inner, field, method
+    public static final int ACC_MANDATED      = 0x8000; // class, inner, field, method
 
     public static enum Kind { Class, InnerClass, Field, Method};
 
@@ -81,12 +81,12 @@
     }
 
     private static final int[] classModifiers = {
-        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
+        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT
     };
 
     private static final int[] classFlags = {
         ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT,
-        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
+        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
     };
 
     public Set<String> getClassModifiers() {
@@ -100,12 +100,12 @@
 
     private static final int[] innerClassModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_ABSTRACT, ACC_MODULE
+        ACC_ABSTRACT
     };
 
     private static final int[] innerClassFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
-        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
+        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
     };
 
     public Set<String> getInnerClassModifiers() {
@@ -119,12 +119,12 @@
 
     private static final int[] fieldModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT, ACC_MODULE
+        ACC_VOLATILE, ACC_TRANSIENT
     };
 
     private static final int[] fieldFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_MODULE
+        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM
     };
 
     public Set<String> getFieldModifiers() {
@@ -137,13 +137,13 @@
 
     private static final int[] methodModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_MODULE
+        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT
     };
 
     private static final int[] methodFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
         ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT,
-        ACC_STRICT, ACC_SYNTHETIC, ACC_MODULE
+        ACC_STRICT, ACC_SYNTHETIC
     };
 
     public Set<String> getMethodModifiers() {
@@ -208,8 +208,8 @@
                 return "abstract";
             case ACC_STRICT:
                 return "strictfp";
-            case ACC_MODULE:
-                return "module";
+            case ACC_MANDATED:
+                return "mandated";
             default:
                 return null;
         }
@@ -247,8 +247,8 @@
             return "ACC_ANNOTATION";
         case ACC_ENUM:
             return "ACC_ENUM";
-        case ACC_MODULE:
-            return "ACC_MODULE";
+        case ACC_MANDATED:
+            return "ACC_MANDATED";
         default:
             return null;
         }
--- a/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Sun Feb 17 16:44:55 2013 -0500
@@ -727,12 +727,13 @@
         private void write(TypeAnnotation.Position p, ClassOutputStream out) {
             out.writeByte(p.type.targetTypeValue());
             switch (p.type) {
-            // type cast
-            case CAST:
             // instanceof
             case INSTANCEOF:
             // new expression
             case NEW:
+            // constructor/method reference receiver
+            case CONSTRUCTOR_REFERENCE:
+            case METHOD_REFERENCE:
                 out.writeShort(p.offset);
                 break;
             // local variable
@@ -779,9 +780,12 @@
             case METHOD_FORMAL_PARAMETER:
                 out.writeByte(p.parameter_index);
                 break;
+            // type cast
+            case CAST:
             // method/constructor/reference type argument
             case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
             case METHOD_INVOCATION_TYPE_ARGUMENT:
+            case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
             case METHOD_REFERENCE_TYPE_ARGUMENT:
                 out.writeShort(p.offset);
                 out.writeByte(p.type_index);
@@ -790,10 +794,6 @@
             case METHOD_RETURN:
             case FIELD:
                 break;
-            // lambda formal parameter
-            case LAMBDA_FORMAL_PARAMETER:
-                out.writeByte(p.parameter_index);
-                break;
             case UNKNOWN:
                 throw new AssertionError("ClassWriter: UNKNOWN target type should never occur!");
             default:
--- a/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java	Sun Feb 17 16:44:55 2013 -0500
@@ -86,12 +86,13 @@
         position.type = type;
 
         switch (type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             position.offset = cr.readUnsignedShort();
             break;
         // local variable
@@ -142,9 +143,12 @@
         case METHOD_FORMAL_PARAMETER:
             position.parameter_index = cr.readUnsignedByte();
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             position.offset = cr.readUnsignedShort();
             position.type_index = cr.readUnsignedByte();
@@ -153,10 +157,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            position.parameter_index = cr.readUnsignedByte();
-            break;
         case UNKNOWN:
             throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
         default:
@@ -177,13 +177,14 @@
         int n = 0;
         n += 1; // TargetType tag is a byte
         switch (pos.type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
-            n += 2;
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
+            n += 2; // offset
             break;
         // local variable
         case LOCAL_VARIABLE:
@@ -192,7 +193,7 @@
             n += 2; // table_length;
             int table_length = pos.lvarOffset.length;
             n += 2 * table_length; // offset
-            n += 2 * table_length; // length;
+            n += 2 * table_length; // length
             n += 2 * table_length; // index
             break;
         // exception parameter
@@ -206,7 +207,7 @@
         // type parameter
         case CLASS_TYPE_PARAMETER:
         case METHOD_TYPE_PARAMETER:
-            n += 1; // parameter_index;
+            n += 1; // parameter_index
             break;
         // type parameter bound
         case CLASS_TYPE_PARAMETER_BOUND:
@@ -226,9 +227,12 @@
         case METHOD_FORMAL_PARAMETER:
             n += 1; // parameter_index
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             n += 2; // offset
             n += 1; // type index
@@ -237,10 +241,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            n += 1; // parameter_index
-            break;
         case UNKNOWN:
             throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
         default:
@@ -377,12 +377,13 @@
             sb.append(type);
 
             switch (type) {
-            // type cast
-            case CAST:
             // instanceof
             case INSTANCEOF:
             // new expression
             case NEW:
+            // constructor/method reference receiver
+            case CONSTRUCTOR_REFERENCE:
+            case METHOD_REFERENCE:
                 sb.append(", offset = ");
                 sb.append(offset);
                 break;
@@ -444,9 +445,12 @@
                 sb.append(", param_index = ");
                 sb.append(parameter_index);
                 break;
+            // type cast
+            case CAST:
             // method/constructor/reference type argument
             case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
             case METHOD_INVOCATION_TYPE_ARGUMENT:
+            case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
             case METHOD_REFERENCE_TYPE_ARGUMENT:
                 sb.append(", offset = ");
                 sb.append(offset);
@@ -457,12 +461,6 @@
             case METHOD_RETURN:
             case FIELD:
                 break;
-            // lambda formal parameter
-            case LAMBDA_FORMAL_PARAMETER:
-                // TODO: also needs an offset?
-                sb.append(", param_index = ");
-                sb.append(parameter_index);
-                break;
             case UNKNOWN:
                 sb.append(", position UNKNOWN!");
                 break;
@@ -564,34 +562,37 @@
         /** For annotations on an exception parameter. */
         EXCEPTION_PARAMETER(0x42, true),
 
-        /** For annotations on a typecast. */
-        CAST(0x43, true),
-
         /** For annotations on a type test. */
-        INSTANCEOF(0x44, true),
+        INSTANCEOF(0x43, true),
 
         /** For annotations on an object creation expression. */
-        NEW(0x45, true),
+        NEW(0x44, true),
+
+        /** For annotations on a constructor reference receiver. */
+        CONSTRUCTOR_REFERENCE(0x45, true),
+
+        /** For annotations on a method reference receiver. */
+        METHOD_REFERENCE(0x46, true),
+
+        /** For annotations on a typecast. */
+        CAST(0x47, true),
 
         /** For annotations on a type argument of an object creation expression. */
-        CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
+        CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
 
         /** For annotations on a type argument of a method call. */
-        METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
+        METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
 
-        /** For annotations on a lambda parameter type. */
-        LAMBDA_FORMAL_PARAMETER(0x48, true),
-
-        /** For annotations on a method reference. */
-        METHOD_REFERENCE(0x49, true),
+        /** For annotations on a type argument of a constructor reference. */
+        CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
 
         /** For annotations on a type argument of a method reference. */
-        METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
+        METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
 
         /** For annotations with an unknown target. */
         UNKNOWN(0xFF);
 
-        private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x50;
+        private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
 
         private final int targetTypeValue;
         private final boolean isLocal;
--- a/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/PackageIndexWriter.java	Sun Feb 17 16:44:55 2013 -0500
@@ -237,10 +237,7 @@
     protected void addOverviewComment(Content htmltree) {
         if (root.inlineTags().length > 0) {
             htmltree.addContent(getMarkerAnchor("overview_description"));
-            HtmlTree div = new HtmlTree(HtmlTag.DIV);
-            div.addStyle(HtmlStyle.subTitle);
-            addInlineComment(root, div);
-            htmltree.addContent(div);
+            addInlineComment(root, htmltree);
         }
     }
 
@@ -252,7 +249,7 @@
      */
     protected void addOverview(Content body) throws IOException {
         HtmlTree div = new HtmlTree(HtmlTag.DIV);
-        div.addStyle(HtmlStyle.footer);
+        div.addStyle(HtmlStyle.contentContainer);
         addOverviewComment(div);
         addTagsInfo(root, div);
         body.addContent(div);
--- a/src/share/classes/com/sun/tools/doclint/Checker.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/doclint/Checker.java	Sun Feb 17 16:44:55 2013 -0500
@@ -245,12 +245,19 @@
         if (t == null) {
             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
         } else {
+            boolean done = false;
             for (TagStackItem tsi: tagStack) {
                 if (tsi.tag.accepts(t)) {
                     while (tagStack.peek() != tsi) tagStack.pop();
+                    done = true;
                     break;
-                } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL)
+                } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL) {
+                    done = true;
                     break;
+                }
+            }
+            if (!done && HtmlTag.BODY.accepts(t)) {
+                tagStack.clear();
             }
 
             checkStructure(tree, t);
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java	Sun Feb 17 16:44:55 2013 -0500
@@ -74,6 +74,7 @@
         if ((mask&DEPRECATED) != 0) flags.add(Flag.DEPRECATED);
         if ((mask&HASINIT) != 0) flags.add(Flag.HASINIT);
         if ((mask&ENUM) != 0) flags.add(Flag.ENUM);
+        if ((mask&MANDATED) != 0) flags.add(Flag.MANDATED);
         if ((mask&IPROXY) != 0) flags.add(Flag.IPROXY);
         if ((mask&NOOUTERTHIS) != 0) flags.add(Flag.NOOUTERTHIS);
         if ((mask&EXISTS) != 0) flags.add(Flag.EXISTS);
@@ -114,6 +115,9 @@
      *  classfile v49.0. */
     public static final int ENUM         = 1<<14;
 
+    /** Added in SE8, represents constructs implicitly declared in source. */
+    public static final int MANDATED     = 1<<15;
+
     public static final int StandardFlags = 0x0fff;
     public static final int ModifierFlags = StandardFlags & ~INTERFACE;
 
@@ -347,6 +351,7 @@
         DEPRECATED("deprecated"),
         HASINIT("hasinit"),
         ENUM("enum"),
+        MANDATED("mandated"),
         IPROXY("iproxy"),
         NOOUTERTHIS("noouterthis"),
         EXISTS("exists"),
--- a/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Sun Feb 17 16:44:55 2013 -0500
@@ -221,7 +221,7 @@
     public boolean allowIntersectionTypesInCast() {
         return compareTo(JDK1_8) >= 0;
     }
-    public boolean allowEarlyReturnConstraints() {
+    public boolean allowGraphInference() {
         return compareTo(JDK1_8) >= 0;
     }
     public boolean allowStructuralMostSpecific() {
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Sun Feb 17 16:44:55 2013 -0500
@@ -217,6 +217,14 @@
         return (flags() & INTERFACE) != 0;
     }
 
+    public boolean isPrivate() {
+        return (flags_field & Flags.AccessFlags) == PRIVATE;
+    }
+
+    public boolean isEnum() {
+        return (flags() & ENUM) != 0;
+    }
+
     /** Is this symbol declared (directly or indirectly) local
      *  to a method or variable initializer?
      *  Also includes fields of inner classes which are in
@@ -479,7 +487,7 @@
     }
 
     // This method is part of the javax.lang.model API, do not use this in javac code.
-    public <A extends java.lang.annotation.Annotation> A[] getAnnotations(Class<A> annoType) {
+    public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A> annoType) {
         return JavacElements.getAnnotations(this, annoType);
     }
 
@@ -496,9 +504,9 @@
         return l.toList();
     }
 
-    public static class DelegatedSymbol extends Symbol {
-        protected Symbol other;
-        public DelegatedSymbol(Symbol other) {
+    public static class DelegatedSymbol<T extends Symbol> extends Symbol {
+        protected T other;
+        public DelegatedSymbol(T other) {
             super(other.kind, other.flags_field, other.name, other.type, other.owner);
             this.other = other;
         }
@@ -532,6 +540,10 @@
         public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
             return v.visitSymbol(other, p);
         }
+
+        public T getUnderlyingSymbol() {
+            return other;
+        }
     }
 
     /** A class for type symbols. Type variables are represented by instances
@@ -1078,6 +1090,9 @@
         /** The code of the method. */
         public Code code = null;
 
+        /** The extra (synthetic/mandated) parameters of the method. */
+        public List<VarSymbol> extraParams = List.nil();
+
         /** The parameters of the method. */
         public List<VarSymbol> params = null;
 
--- a/src/share/classes/com/sun/tools/javac/code/TargetType.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/TargetType.java	Sun Feb 17 16:44:55 2013 -0500
@@ -82,34 +82,37 @@
     /** For annotations on an exception parameter. */
     EXCEPTION_PARAMETER(0x42, true),
 
-    /** For annotations on a typecast. */
-    CAST(0x43, true),
-
     /** For annotations on a type test. */
-    INSTANCEOF(0x44, true),
+    INSTANCEOF(0x43, true),
 
     /** For annotations on an object creation expression. */
-    NEW(0x45, true),
+    NEW(0x44, true),
+
+    /** For annotations on a constructor reference receiver. */
+    CONSTRUCTOR_REFERENCE(0x45, true),
+
+    /** For annotations on a method reference receiver. */
+    METHOD_REFERENCE(0x46, true),
+
+    /** For annotations on a typecast. */
+    CAST(0x47, true),
 
     /** For annotations on a type argument of an object creation expression. */
-    CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
+    CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
 
     /** For annotations on a type argument of a method call. */
-    METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
+    METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
 
-    /** For annotations on a lambda parameter type. */
-    LAMBDA_FORMAL_PARAMETER(0x48, true),
-
-    /** For annotations on a method reference. */
-    METHOD_REFERENCE(0x49, true),
+    /** For annotations on a type argument of a constructor reference. */
+    CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
 
     /** For annotations on a type argument of a method reference. */
-    METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
+    METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
 
     /** For annotations with an unknown target. */
     UNKNOWN(0xFF);
 
-    private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x92;
+    private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
 
     private final int targetTypeValue;
     private final boolean isLocal;
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1309,6 +1309,9 @@
         /** inference variable's inferred type (set from Infer.java) */
         public Type inst = null;
 
+        /** number of declared (upper) bounds */
+        public int declaredCount;
+
         /** inference variable's change listener */
         public UndetVarListener listener = null;
 
@@ -1318,13 +1321,11 @@
         }
 
         public UndetVar(TypeVar origin, Types types) {
-            this(origin, types, true);
-        }
-
-        public UndetVar(TypeVar origin, Types types, boolean includeBounds) {
             super(UNDETVAR, origin);
             bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
-            bounds.put(InferenceBound.UPPER, includeBounds ? types.getBounds(origin) : List.<Type>nil());
+            List<Type> declaredBounds = types.getBounds(origin);
+            declaredCount = declaredBounds.length();
+            bounds.put(InferenceBound.UPPER, declaredBounds);
             bounds.put(InferenceBound.LOWER, List.<Type>nil());
             bounds.put(InferenceBound.EQ, List.<Type>nil());
         }
@@ -1340,38 +1341,89 @@
         }
 
         /** get all bounds of a given kind */
-        public List<Type> getBounds(InferenceBound ib) {
-            return bounds.get(ib);
+        public List<Type> getBounds(InferenceBound... ibs) {
+            ListBuffer<Type> buf = ListBuffer.lb();
+            for (InferenceBound ib : ibs) {
+                buf.appendList(bounds.get(ib));
+            }
+            return buf.toList();
+        }
+
+        /** get the list of declared (upper) bounds */
+        public List<Type> getDeclaredBounds() {
+            ListBuffer<Type> buf = ListBuffer.lb();
+            int count = 0;
+            for (Type b : getBounds(InferenceBound.UPPER)) {
+                if (count++ == declaredCount) break;
+                buf.append(b);
+            }
+            return buf.toList();
         }
 
         /** add a bound of a given kind - this might trigger listener notification */
         public void addBound(InferenceBound ib, Type bound, Types types) {
+            Type bound2 = toTypeVarMap.apply(bound);
             List<Type> prevBounds = bounds.get(ib);
             for (Type b : prevBounds) {
-                if (types.isSameType(b, bound)) {
-                    return;
-                }
+                //check for redundancy - use strict version of isSameType on tvars
+                //(as the standard version will lead to false positives w.r.t. clones ivars)
+                if (types.isSameType(b, bound2, true)) return;
             }
-            bounds.put(ib, prevBounds.prepend(bound));
+            bounds.put(ib, prevBounds.prepend(bound2));
             notifyChange(EnumSet.of(ib));
         }
+        //where
+            Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") {
+                @Override
+                public Type apply(Type t) {
+                    if (t.hasTag(UNDETVAR)) {
+                        UndetVar uv = (UndetVar)t;
+                        return uv.qtype;
+                    } else {
+                        return t.map(this);
+                    }
+                }
+            };
 
         /** replace types in all bounds - this might trigger listener notification */
         public void substBounds(List<Type> from, List<Type> to, Types types) {
-            EnumSet<InferenceBound> changed = EnumSet.noneOf(InferenceBound.class);
-            Map<InferenceBound, List<Type>> bounds2 = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
-            for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
-                InferenceBound ib = _entry.getKey();
-                List<Type> prevBounds = _entry.getValue();
-                List<Type> newBounds = types.subst(prevBounds, from, to);
-                bounds2.put(ib, newBounds);
-                if (prevBounds != newBounds) {
-                    changed.add(ib);
+            List<Type> instVars = from.diff(to);
+            //if set of instantiated ivars is empty, there's nothing to do!
+            if (instVars.isEmpty()) return;
+            final EnumSet<InferenceBound> boundsChanged = EnumSet.noneOf(InferenceBound.class);
+            UndetVarListener prevListener = listener;
+            try {
+                //setup new listener for keeping track of changed bounds
+                listener = new UndetVarListener() {
+                    public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
+                        boundsChanged.addAll(ibs);
+                    }
+                };
+                for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
+                    InferenceBound ib = _entry.getKey();
+                    List<Type> prevBounds = _entry.getValue();
+                    ListBuffer<Type> newBounds = ListBuffer.lb();
+                    ListBuffer<Type> deps = ListBuffer.lb();
+                    //step 1 - re-add bounds that are not dependent on ivars
+                    for (Type t : prevBounds) {
+                        if (!t.containsAny(instVars)) {
+                            newBounds.append(t);
+                        } else {
+                            deps.append(t);
+                        }
+                    }
+                    //step 2 - replace bounds
+                    bounds.put(ib, newBounds.toList());
+                    //step 3 - for each dependency, add new replaced bound
+                    for (Type dep : deps) {
+                        addBound(ib, types.subst(dep, from, to), types);
+                    }
                 }
-            }
-            if (!changed.isEmpty()) {
-                bounds = bounds2;
-                notifyChange(changed);
+            } finally {
+                listener = prevListener;
+                if (!boundsChanged.isEmpty()) {
+                    notifyChange(boundsChanged);
+                }
             }
         }
 
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Sun Feb 17 16:44:55 2013 -0500
@@ -126,7 +126,8 @@
     // Tree position.
     public int pos = -1;
 
-    // For typecasts, type tests, new (and locals, as start_pc).
+    // For type casts, type tests, new, locals (as start_pc),
+    // and method and constructor reference type arguments.
     public boolean isValidOffset = false;
     public int offset = -1;
 
@@ -156,12 +157,13 @@
         sb.append(type);
 
         switch (type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             sb.append(", offset = ");
             sb.append(offset);
             break;
@@ -223,9 +225,12 @@
             sb.append(", param_index = ");
             sb.append(parameter_index);
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             sb.append(", offset = ");
             sb.append(offset);
@@ -236,12 +241,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            // TODO: also needs an offset?
-            sb.append(", param_index = ");
-            sb.append(parameter_index);
-            break;
         case UNKNOWN:
             sb.append(", position UNKNOWN!");
             break;
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Sun Feb 17 16:44:55 2013 -0500
@@ -217,6 +217,9 @@
         // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
         // need to set its position explicitly.
         // The method returns a copy of type that contains these annotations.
+        //
+        // As a side effect the method sets the type annotation position of "annotations".
+        // Note that it is assumed that all annotations share the same position.
         private static Type typeWithAnnotations(final JCTree typetree, final Type type,
                 final List<Attribute.TypeCompound> annotations, Log log) {
             // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n",
@@ -267,7 +270,9 @@
                 }
                 Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log);
                 tomodify.elemtype = arelemType;
-                for (Attribute.TypeCompound a : annotations) {
+                {
+                    // All annotations share the same position; modify the first one.
+                    Attribute.TypeCompound a = annotations.get(0);
                     TypeAnnotationPosition p = a.position;
                     p.location = p.location.prependList(depth.toList());
                 }
@@ -345,10 +350,10 @@
                 if (depth.nonEmpty()) {
                     // Only need to change the annotation positions
                     // if they are on an enclosed type.
-                    for (Attribute.TypeCompound a : annotations) {
-                        TypeAnnotationPosition p = a.position;
-                        p.location = p.location.appendList(depth.toList());
-                    }
+                    // All annotations share the same position; modify the first one.
+                    Attribute.TypeCompound a = annotations.get(0);
+                    TypeAnnotationPosition p = a.position;
+                    p.location = p.location.appendList(depth.toList());
                 }
 
                 Type ret = typeWithAnnotations(type, enclTy, annotations);
@@ -463,8 +468,7 @@
 
                 @Override
                 public Type visitType(Type t, List<TypeCompound> s) {
-                    // Error?
-                    return t;
+                    return new AnnotatedType(s, t);
                 }
             };
 
@@ -575,6 +579,10 @@
             System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
             System.out.println("    Framing tree: " + frame + " kind: " + frame.getKind());
             */
+
+            // Note that p.offset is set in
+            // com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int)
+
             switch (frame.getKind()) {
                 case TYPE_CAST:
                     p.type = TargetType.CAST;
@@ -659,6 +667,45 @@
                     return;
                 }
 
+                case MEMBER_REFERENCE: {
+                    JCMemberReference mrframe = (JCMemberReference) frame;
+
+                    if (mrframe.expr == tree) {
+                        switch (mrframe.mode) {
+                        case INVOKE:
+                            p.type = TargetType.METHOD_REFERENCE;
+                            break;
+                        case NEW:
+                            p.type = TargetType.CONSTRUCTOR_REFERENCE;
+                            break;
+                        default:
+                            Assert.error("Unknown method reference mode " + mrframe.mode +
+                                    " for tree " + tree + " within frame " + frame);
+                        }
+                        p.pos = frame.pos;
+                    } else if (mrframe.typeargs != null &&
+                            mrframe.typeargs.contains(tree)) {
+                        int arg = mrframe.typeargs.indexOf(tree);
+                        p.type_index = arg;
+                        switch (mrframe.mode) {
+                        case INVOKE:
+                            p.type = TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
+                            break;
+                        case NEW:
+                            p.type = TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
+                            break;
+                        default:
+                            Assert.error("Unknown method reference mode " + mrframe.mode +
+                                    " for tree " + tree + " within frame " + frame);
+                        }
+                        p.pos = frame.pos;
+                    } else {
+                        Assert.error("Could not determine type argument position of tree " + tree +
+                                " within frame " + frame);
+                    }
+                    return;
+                }
+
                 case ARRAY_TYPE: {
                     ListBuffer<TypePathEntry> index = ListBuffer.lb();
                     index = index.append(TypePathEntry.ARRAY);
@@ -766,6 +813,14 @@
                     return;
                 }
 
+                case INTERSECTION_TYPE: {
+                    JCTypeIntersection isect = (JCTypeIntersection)frame;
+                    p.type_index = isect.bounds.indexOf(tree);
+                    List<JCTree> newPath = path.tail;
+                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                    return;
+                }
+
                 case METHOD_INVOCATION: {
                     JCMethodInvocation invocation = (JCMethodInvocation)frame;
                     if (!invocation.typeargs.contains(tree)) {
@@ -911,6 +966,8 @@
         public void visitVarDef(final JCVariableDecl tree) {
             if (tree.sym == null) {
                 // Something is wrong already. Quietly ignore.
+            } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
+                // Parameters are handled in visitMethodDef above.
             } else if (tree.sym.getKind() == ElementKind.FIELD) {
                 if (sigOnly) {
                     TypeAnnotationPosition pos = new TypeAnnotationPosition();
@@ -924,7 +981,6 @@
                 pos.pos = tree.pos;
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
-                // System.out.println("Found exception param: " + tree);
                 TypeAnnotationPosition pos = new TypeAnnotationPosition();
                 pos.type = TargetType.EXCEPTION_PARAMETER;
                 pos.pos = tree.pos;
@@ -934,9 +990,11 @@
                 pos.type = TargetType.RESOURCE_VARIABLE;
                 pos.pos = tree.pos;
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+            } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
+                // No type annotations can occur here.
             } else {
                 // There is nothing else in a variable declaration that needs separation.
-                // System.out.println("We found a: " + tree);
+                Assert.error("Unhandled variable kind: " + tree + " of kind: " + tree.sym.getKind());
             }
 
             push(tree);
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Sun Feb 17 16:44:55 2013 -0500
@@ -976,9 +976,12 @@
      * lists are of different length, return false.
      */
     public boolean isSameTypes(List<Type> ts, List<Type> ss) {
+        return isSameTypes(ts, ss, false);
+    }
+    public boolean isSameTypes(List<Type> ts, List<Type> ss, boolean strict) {
         while (ts.tail != null && ss.tail != null
                /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
-               isSameType(ts.head, ss.head)) {
+               isSameType(ts.head, ss.head, strict)) {
             ts = ts.tail;
             ss = ss.tail;
         }
@@ -990,10 +993,15 @@
      * Is t the same type as s?
      */
     public boolean isSameType(Type t, Type s) {
-        return isSameType.visit(t, s);
+        return isSameType(t, s, false);
+    }
+    public boolean isSameType(Type t, Type s, boolean strict) {
+        return strict ?
+                isSameTypeStrict.visit(t, s) :
+                isSameTypeLoose.visit(t, s);
     }
     // where
-        private TypeRelation isSameType = new TypeRelation() {
+        abstract class SameTypeVisitor extends TypeRelation {
 
             public Boolean visitType(Type t, Type s) {
                 if (t == s)
@@ -1010,8 +1018,7 @@
                     if (s.tag == TYPEVAR) {
                         //type-substitution does not preserve type-var types
                         //check that type var symbols and bounds are indeed the same
-                        return t.tsym == s.tsym &&
-                                visit(t.getUpperBound(), s.getUpperBound());
+                        return sameTypeVars((TypeVar)t, (TypeVar)s);
                     }
                     else {
                         //special case for s == ? super X, where upper(s) = u
@@ -1026,6 +1033,8 @@
                 }
             }
 
+            abstract boolean sameTypeVars(TypeVar tv1, TypeVar tv2);
+
             @Override
             public Boolean visitWildcardType(WildcardType t, Type s) {
                 if (s.isPartial())
@@ -1060,9 +1069,11 @@
                 }
                 return t.tsym == s.tsym
                     && visit(t.getEnclosingType(), s.getEnclosingType())
-                    && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
+                    && containsTypes(t.getTypeArguments(), s.getTypeArguments());
             }
 
+            abstract protected boolean containsTypes(List<Type> ts1, List<Type> ts2);
+
             @Override
             public Boolean visitArrayType(ArrayType t, Type s) {
                 if (t == s)
@@ -1115,6 +1126,36 @@
             public Boolean visitErrorType(ErrorType t, Type s) {
                 return true;
             }
+        }
+
+        /**
+         * Standard type-equality relation - type variables are considered
+         * equals if they share the same type symbol.
+         */
+        TypeRelation isSameTypeLoose = new SameTypeVisitor() {
+            @Override
+            boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
+                return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound());
+            }
+            @Override
+            protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
+                return containsTypeEquivalent(ts1, ts2);
+            }
+        };
+
+        /**
+         * Strict type-equality relation - type variables are considered
+         * equals if they share the same object identity.
+         */
+        TypeRelation isSameTypeStrict = new SameTypeVisitor() {
+            @Override
+            boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
+                return tv1 == tv2;
+            }
+            @Override
+            protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
+                return isSameTypes(ts1, ts2, true);
+            }
         };
     // </editor-fold>
 
@@ -2027,7 +2068,15 @@
 
             @Override
             public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
-                return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse));
+                Type erased = erasure(t.underlyingType, recurse);
+                if (erased.getKind() == TypeKind.ANNOTATED) {
+                    // This can only happen when the underlying type is a
+                    // type variable and the upper bound of it is annotated.
+                    // The annotation on the type variable overrides the one
+                    // on the bound.
+                    erased = ((AnnotatedType)erased).underlyingType;
+                }
+                return new AnnotatedType(t.typeAnnotations, erased);
             }
         };
 
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sun Feb 17 16:44:55 2013 -0500
@@ -43,7 +43,7 @@
 import com.sun.tools.javac.comp.Check.CheckContext;
 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
-import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
@@ -244,8 +244,8 @@
                     @Override
                     public void typesInferred(InferenceContext inferenceContext) {
                         ResultInfo pendingResult =
-                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types));
-                        check(tree, inferenceContext.asInstType(found, types), ownkind, pendingResult);
+                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
+                        check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
                     }
                 });
                 return tree.type = resultInfo.pt;
@@ -766,6 +766,8 @@
         JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
 
         try {
+            memberEnter.typeAnnotate(initializer, env, env.info.enclVar);
+            annotate.flush();
             Type itype = attribExpr(initializer, env, type);
             if (itype.constValue() != null)
                 return coerce(itype, type).constValue();
@@ -1099,8 +1101,9 @@
             Env<AttrContext> localEnv =
                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
             localEnv.info.scope.owner =
-                new MethodSymbol(tree.flags | BLOCK, names.empty, null,
-                                 env.info.scope.owner);
+                new MethodSymbol(tree.flags | BLOCK |
+                    env.info.scope.owner.flags() & STRICTFP, names.empty, null,
+                    env.info.scope.owner);
             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
 
             // Attribute all type annotations in the block
@@ -2415,7 +2418,7 @@
                 inferenceContext.addFreeTypeListener(ts, new FreeTypeListener() {
                     @Override
                     public void typesInferred(InferenceContext inferenceContext) {
-                        checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts, types));
+                        checkAccessibleTypes(pos, env, inferenceContext, inferenceContext.asInstTypes(ts));
                     }
                 });
             } else {
@@ -2440,7 +2443,7 @@
             @Override
             public boolean compatible(Type found, Type req, Warner warn) {
                 //return type must be compatible in both current context and assignment context
-                return chk.basicHandler.compatible(found, inferenceContext().asFree(req, types), warn);
+                return chk.basicHandler.compatible(found, inferenceContext().asFree(req), warn);
             }
 
             @Override
@@ -2475,7 +2478,7 @@
         * descriptor.
         */
         private void checkLambdaCompatible(JCLambda tree, Type descriptor, CheckContext checkContext, boolean speculativeAttr) {
-            Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types);
+            Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType());
 
             //return values have already been checked - but if lambda has no return
             //values, we must ensure that void/value compatibility is correct;
@@ -2487,13 +2490,13 @@
                         diags.fragment("missing.ret.val", returnType)));
             }
 
-            List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes(), types);
+            List<Type> argTypes = checkContext.inferenceContext().asFree(descriptor.getParameterTypes());
             if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) {
                 checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
             }
 
             if (!speculativeAttr) {
-                List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types);
+                List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes());
                 if (chk.unhandled(tree.inferredThrownTypes == null ? List.<Type>nil() : tree.inferredThrownTypes, thrownTypes).nonEmpty()) {
                     log.error(tree, "incompatible.thrown.types.in.lambda", tree.inferredThrownTypes);
                 }
@@ -2538,7 +2541,7 @@
 
             if (exprType.isErroneous()) {
                 //if the qualifier expression contains problems,
-                //give up atttribution of method reference
+                //give up attribution of method reference
                 result = that.type = exprType;
                 return;
             }
@@ -2680,7 +2683,7 @@
 
     @SuppressWarnings("fallthrough")
     void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) {
-        Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType(), types);
+        Type returnType = checkContext.inferenceContext().asFree(descriptor.getReturnType());
 
         Type resType;
         switch (tree.getMode()) {
@@ -2712,7 +2715,7 @@
         }
 
         if (!speculativeAttr) {
-            List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes(), types);
+            List<Type> thrownTypes = checkContext.inferenceContext().asFree(descriptor.getThrownTypes());
             if (chk.unhandled(refType.getThrownTypes(), thrownTypes).nonEmpty()) {
                 log.error(tree, "incompatible.thrown.types.in.mref", refType.getThrownTypes());
             }
@@ -2728,7 +2731,7 @@
         if (inferenceContext.free(descriptorType)) {
             inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() {
                 public void typesInferred(InferenceContext inferenceContext) {
-                    setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType, types), inferenceContext);
+                    setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), inferenceContext);
                 }
             });
         } else {
@@ -4152,7 +4155,9 @@
         }
 
     private Type capture(Type type) {
-        return types.capture(type);
+        //do not capture free types
+        return resultInfo.checkContext.inferenceContext().free(type) ?
+                type : types.capture(type);
     }
 
     private void validateTypeAnnotations(JCTree tree) {
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Sun Feb 17 16:44:55 2013 -0500
@@ -42,7 +42,7 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
-import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 
@@ -533,7 +533,7 @@
             inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() {
                 @Override
                 public void typesInferred(InferenceContext inferenceContext) {
-                    checkType(pos, found, inferenceContext.asInstType(req, types), checkContext);
+                    checkType(pos, found, inferenceContext.asInstType(req), checkContext);
                 }
             });
         }
@@ -1026,7 +1026,7 @@
         };
 
     /** Check that given modifiers are legal for given symbol and
-     *  return modifiers together with any implicit modififiers for that symbol.
+     *  return modifiers together with any implicit modifiers for that symbol.
      *  Warning: we can't use flags() here since this method
      *  is called during class enter, when flags() would cause a premature
      *  completion.
@@ -1072,7 +1072,7 @@
             }
             // Imply STRICTFP if owner has STRICTFP set.
             if (((flags|implicit) & Flags.ABSTRACT) == 0)
-              implicit |= sym.owner.flags_field & STRICTFP;
+                implicit |= sym.owner.flags_field & STRICTFP;
             break;
         case TYP:
             if (sym.isLocal()) {
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Sun Feb 17 16:44:55 2013 -0500
@@ -234,7 +234,7 @@
                     dt.speculativeCache.put(deferredAttrContext.msym, speculativeTree, deferredAttrContext.phase);
                     return speculativeTree.type;
                 case CHECK:
-                    Assert.check(dt.mode == AttrMode.SPECULATIVE);
+                    Assert.check(dt.mode != null);
                     return attr.attribTree(dt.tree, dt.env, resultInfo);
             }
             Assert.error();
@@ -242,6 +242,13 @@
         }
     };
 
+    DeferredTypeCompleter dummyCompleter = new DeferredTypeCompleter() {
+        public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
+            Assert.check(deferredAttrContext.mode == AttrMode.CHECK);
+            return dt.tree.type = Type.noType;
+        }
+    };
+
     /**
      * The 'mode' in which the deferred type is to be type-checked
      */
@@ -332,13 +339,22 @@
         /** inference context */
         final InferenceContext inferenceContext;
 
+        /** parent deferred context */
+        final DeferredAttrContext parent;
+
+        /** Warner object to report warnings */
+        final Warner warn;
+
         /** list of deferred attribution nodes to be processed */
         ArrayList<DeferredAttrNode> deferredAttrNodes = new ArrayList<DeferredAttrNode>();
 
-        DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase, InferenceContext inferenceContext) {
+        DeferredAttrContext(AttrMode mode, Symbol msym, MethodResolutionPhase phase,
+                InferenceContext inferenceContext, DeferredAttrContext parent, Warner warn) {
             this.mode = mode;
             this.msym = msym;
             this.phase = phase;
+            this.parent = parent;
+            this.warn = warn;
             this.inferenceContext = inferenceContext;
         }
 
@@ -363,7 +379,7 @@
                 //scan a defensive copy of the node list - this is because a deferred
                 //attribution round can add new nodes to the list
                 for (DeferredAttrNode deferredAttrNode : List.from(deferredAttrNodes)) {
-                    if (!deferredAttrNode.process()) {
+                    if (!deferredAttrNode.process(this)) {
                         stuckVars.addAll(deferredAttrNode.stuckVars);
                     } else {
                         deferredAttrNodes.remove(deferredAttrNode);
@@ -373,123 +389,133 @@
                 if (!progress) {
                     //remove all variables that have already been instantiated
                     //from the list of stuck variables
-                    inferenceContext.solveAny(inferenceContext.freeVarsIn(List.from(stuckVars)), types, infer);
-                    inferenceContext.notifyChange(types);
+                    inferenceContext.solveAny(List.from(stuckVars), warn);
+                    inferenceContext.notifyChange();
                 }
             }
         }
+    }
+
+    /**
+     * Class representing a deferred attribution node. It keeps track of
+     * a deferred type, along with the expected target type information.
+     */
+    class DeferredAttrNode implements Infer.FreeTypeListener {
+
+        /** underlying deferred type */
+        DeferredType dt;
+
+        /** underlying target type information */
+        ResultInfo resultInfo;
+
+        /** list of uninferred inference variables causing this node to be stuck */
+        List<Type> stuckVars;
+
+        DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
+            this.dt = dt;
+            this.resultInfo = resultInfo;
+            this.stuckVars = stuckVars;
+            if (!stuckVars.isEmpty()) {
+                resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
+            }
+        }
+
+        @Override
+        public void typesInferred(InferenceContext inferenceContext) {
+            stuckVars = List.nil();
+            resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
+        }
+
+        /**
+         * Process a deferred attribution node.
+         * Invariant: a stuck node cannot be processed.
+         */
+        @SuppressWarnings("fallthrough")
+        boolean process(DeferredAttrContext deferredAttrContext) {
+            switch (deferredAttrContext.mode) {
+                case SPECULATIVE:
+                    dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
+                    return true;
+                case CHECK:
+                    if (stuckVars.nonEmpty()) {
+                        //stuck expression - see if we can propagate
+                        if (deferredAttrContext.parent != emptyDeferredAttrContext &&
+                                Type.containsAny(deferredAttrContext.parent.inferenceContext.inferencevars, List.from(stuckVars))) {
+                            deferredAttrContext.parent.deferredAttrNodes.add(this);
+                            dt.check(resultInfo, List.<Type>nil(), dummyCompleter);
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    } else {
+                        dt.check(resultInfo, stuckVars, basicCompleter);
+                        return true;
+                    }
+                default:
+                    throw new AssertionError("Bad mode");
+            }
+        }
 
         /**
-         * Class representing a deferred attribution node. It keeps track of
-         * a deferred type, along with the expected target type information.
+         * Structural checker for stuck expressions
          */
-        class DeferredAttrNode implements Infer.InferenceContext.FreeTypeListener {
+        class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
 
-            /** underlying deferred type */
-            DeferredType dt;
+            ResultInfo resultInfo;
+            InferenceContext inferenceContext;
 
-            /** underlying target type information */
-            ResultInfo resultInfo;
+            public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
+                this.resultInfo = resultInfo;
+                this.inferenceContext = deferredAttrContext.inferenceContext;
+                dt.tree.accept(this);
+                dt.speculativeCache.put(deferredAttrContext.msym, stuckTree, deferredAttrContext.phase);
+                return Type.noType;
+            }
 
-            /** list of uninferred inference variables causing this node to be stuck */
-            List<Type> stuckVars;
-
-            DeferredAttrNode(DeferredType dt, ResultInfo resultInfo, List<Type> stuckVars) {
-                this.dt = dt;
-                this.resultInfo = resultInfo;
-                this.stuckVars = stuckVars;
-                if (!stuckVars.isEmpty()) {
-                    resultInfo.checkContext.inferenceContext().addFreeTypeListener(stuckVars, this);
+            @Override
+            public void visitLambda(JCLambda tree) {
+                Check.CheckContext checkContext = resultInfo.checkContext;
+                Type pt = resultInfo.pt;
+                if (inferenceContext.inferencevars.contains(pt)) {
+                    //ok
+                    return;
+                } else {
+                    //must be a functional descriptor
+                    try {
+                        Type desc = types.findDescriptorType(pt);
+                        if (desc.getParameterTypes().length() != tree.params.length()) {
+                            checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
+                        }
+                    } catch (Types.FunctionDescriptorLookupError ex) {
+                        checkContext.report(null, ex.getDiagnostic());
+                    }
                 }
             }
 
             @Override
-            public void typesInferred(InferenceContext inferenceContext) {
-                stuckVars = List.nil();
-                resultInfo = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt, types));
+            public void visitNewClass(JCNewClass tree) {
+                //do nothing
             }
 
-            /**
-             * Process a deferred attribution node.
-             * Invariant: a stuck node cannot be processed.
-             */
-            @SuppressWarnings("fallthrough")
-            boolean process() {
-                switch (mode) {
-                    case SPECULATIVE:
-                        dt.check(resultInfo, List.<Type>nil(), new StructuralStuckChecker());
-                        return true;
-                    case CHECK:
-                        if (stuckVars.nonEmpty()) {
-                            return false;
-                        } else {
-                            dt.check(resultInfo, stuckVars, basicCompleter);
-                            return true;
-                        }
-                    default:
-                        throw new AssertionError("Bad mode");
-                }
+            @Override
+            public void visitApply(JCMethodInvocation tree) {
+                //do nothing
             }
 
-            /**
-             * Structural checker for stuck expressions
-             */
-            class StructuralStuckChecker extends TreeScanner implements DeferredTypeCompleter {
-
-                ResultInfo resultInfo;
-
-                public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) {
-                    this.resultInfo = resultInfo;
-                    dt.tree.accept(this);
-                    dt.speculativeCache.put(msym, stuckTree, phase);
-                    return Type.noType;
-                }
-
-                @Override
-                public void visitLambda(JCLambda tree) {
-                    Check.CheckContext checkContext = resultInfo.checkContext;
-                    Type pt = resultInfo.pt;
-                    if (inferenceContext.inferencevars.contains(pt)) {
-                        //ok
-                        return;
-                    } else {
-                        //must be a functional descriptor
-                        try {
-                            Type desc = types.findDescriptorType(pt);
-                            if (desc.getParameterTypes().length() != tree.params.length()) {
-                                checkContext.report(tree, diags.fragment("incompatible.arg.types.in.lambda"));
-                            }
-                        } catch (Types.FunctionDescriptorLookupError ex) {
-                            checkContext.report(null, ex.getDiagnostic());
-                        }
-                    }
-                }
-
-                @Override
-                public void visitNewClass(JCNewClass tree) {
-                    //do nothing
-                }
-
-                @Override
-                public void visitApply(JCMethodInvocation tree) {
-                    //do nothing
-                }
-
-                @Override
-                public void visitReference(JCMemberReference tree) {
-                    Check.CheckContext checkContext = resultInfo.checkContext;
-                    Type pt = resultInfo.pt;
-                    if (inferenceContext.inferencevars.contains(pt)) {
-                        //ok
-                        return;
-                    } else {
-                        try {
-                            //TODO: we should speculative determine if there's a match
-                            //based on arity - if yes, method is applicable.
-                            types.findDescriptorType(pt);
-                        } catch (Types.FunctionDescriptorLookupError ex) {
-                            checkContext.report(null, ex.getDiagnostic());
-                        }
+            @Override
+            public void visitReference(JCMemberReference tree) {
+                Check.CheckContext checkContext = resultInfo.checkContext;
+                Type pt = resultInfo.pt;
+                if (inferenceContext.inferencevars.contains(pt)) {
+                    //ok
+                    return;
+                } else {
+                    try {
+                        //TODO: we should speculative determine if there's a match
+                        //based on arity - if yes, method is applicable.
+                        types.findDescriptorType(pt);
+                    } catch (Types.FunctionDescriptorLookupError ex) {
+                        checkContext.report(null, ex.getDiagnostic());
                     }
                 }
             }
@@ -498,7 +524,7 @@
 
     /** an empty deferred attribution context - all methods throw exceptions */
     final DeferredAttrContext emptyDeferredAttrContext =
-            new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null) {
+            new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, null, null, null) {
                 @Override
                 void addDeferredAttrNode(DeferredType dt, ResultInfo ri, List<Type> stuckVars) {
                     Assert.error("Empty deferred context!");
@@ -521,7 +547,8 @@
 
         protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
             super(String.format("deferredTypeMap[%s]", mode));
-            this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase, infer.emptyContext);
+            this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase,
+                    infer.emptyContext, emptyDeferredAttrContext, types.noWarnings);
         }
 
         protected boolean validState(DeferredType dt) {
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,22 +25,30 @@
 
 package com.sun.tools.javac.comp;
 
-import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.code.Type.*;
-import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
-import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
-import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
-import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCTypeCast;
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
+import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph;
+import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
+import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
+import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
 
 import static com.sun.tools.javac.code.TypeTag.*;
 
@@ -55,19 +63,15 @@
     protected static final Context.Key<Infer> inferKey =
         new Context.Key<Infer>();
 
-    /** A value for prototypes that admit any type, including polymorphic ones. */
-    public static final Type anyPoly = new Type(NONE, null);
-
+    Resolve rs;
+    Check chk;
     Symtab syms;
     Types types;
-    Check chk;
-    Resolve rs;
-    DeferredAttr deferredAttr;
+    JCDiagnostic.Factory diags;
     Log log;
-    JCDiagnostic.Factory diags;
 
-    /** Should we inject return-type constraints earlier? */
-    boolean allowEarlyReturnConstraints;
+    /** should the graph solver be used? */
+    boolean allowGraphInference;
 
     public static Infer instance(Context context) {
         Infer instance = context.get(inferKey);
@@ -78,17 +82,22 @@
 
     protected Infer(Context context) {
         context.put(inferKey, this);
+
+        rs = Resolve.instance(context);
+        chk = Check.instance(context);
         syms = Symtab.instance(context);
         types = Types.instance(context);
-        rs = Resolve.instance(context);
-        deferredAttr = DeferredAttr.instance(context);
+        diags = JCDiagnostic.Factory.instance(context);
         log = Log.instance(context);
-        chk = Check.instance(context);
-        diags = JCDiagnostic.Factory.instance(context);
         inferenceException = new InferenceException(diags);
-        allowEarlyReturnConstraints = Source.instance(context).allowEarlyReturnConstraints();
+        Options options = Options.instance(context);
+        allowGraphInference = Source.instance(context).allowGraphInference()
+                && options.isUnset("useLegacyInference");
     }
 
+    /** A value for prototypes that admit any type, including polymorphic ones. */
+    public static final Type anyPoly = new Type(NONE, null);
+
    /**
     * This exception class is design to store a list of diagnostics corresponding
     * to inference errors that can arise during a method applicability check.
@@ -118,140 +127,12 @@
         }
     }
 
-    final InferenceException inferenceException;
+    protected final InferenceException inferenceException;
 
-/***************************************************************************
- * Mini/Maximization of UndetVars
- ***************************************************************************/
-
-    /** Instantiate undetermined type variable to its minimal upper bound.
-     *  Throw a NoInstanceException if this not possible.
-     */
-   void maximizeInst(UndetVar that, Warner warn) throws InferenceException {
-        List<Type> hibounds = Type.filter(that.getBounds(InferenceBound.UPPER), boundFilter);
-        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
-            if (hibounds.isEmpty())
-                that.inst = syms.objectType;
-            else if (hibounds.tail.isEmpty())
-                that.inst = hibounds.head;
-            else
-                that.inst = types.glb(hibounds);
-        } else {
-            that.inst = that.getBounds(InferenceBound.EQ).head;
-        }
-        if (that.inst == null ||
-            that.inst.isErroneous())
-            throw inferenceException
-                .setMessage("no.unique.maximal.instance.exists",
-                            that.qtype, hibounds);
-    }
-
-    private Filter<Type> boundFilter = new Filter<Type>() {
-        @Override
-        public boolean accepts(Type t) {
-            return !t.isErroneous() && !t.hasTag(BOT);
-        }
-    };
-
-    /** Instantiate undetermined type variable to the lub of all its lower bounds.
-     *  Throw a NoInstanceException if this not possible.
-     */
-    void minimizeInst(UndetVar that, Warner warn) throws InferenceException {
-        List<Type> lobounds = Type.filter(that.getBounds(InferenceBound.LOWER), boundFilter);
-        if (that.getBounds(InferenceBound.EQ).isEmpty()) {
-            if (lobounds.isEmpty()) {
-                //do nothing - the inference variable is under-constrained
-                return;
-            } else if (lobounds.tail.isEmpty())
-                that.inst = lobounds.head.isPrimitive() ? syms.errType : lobounds.head;
-            else {
-                that.inst = types.lub(lobounds);
-            }
-            if (that.inst == null || that.inst.hasTag(ERROR))
-                    throw inferenceException
-                        .setMessage("no.unique.minimal.instance.exists",
-                                    that.qtype, lobounds);
-        } else {
-            that.inst = that.getBounds(InferenceBound.EQ).head;
-        }
-    }
-
-/***************************************************************************
- * Exported Methods
- ***************************************************************************/
-
+    // <editor-fold defaultstate="collapsed" desc="Inference routines">
     /**
-     * Instantiate uninferred inference variables (JLS 15.12.2.8). First
-     * if the method return type is non-void, we derive constraints from the
-     * expected type - then we use declared bound well-formedness to derive additional
-     * constraints. If no instantiation exists, or if several incomparable
-     * best instantiations exist throw a NoInstanceException.
-     */
-    public void instantiateUninferred(DiagnosticPosition pos,
-            InferenceContext inferenceContext,
-            MethodType mtype,
-            Attr.ResultInfo resultInfo,
-            Warner warn) throws InferenceException {
-        while (true) {
-            boolean stuck = true;
-            for (Type t : inferenceContext.undetvars) {
-                UndetVar uv = (UndetVar)t;
-                if (uv.inst == null && (uv.getBounds(InferenceBound.EQ).nonEmpty() ||
-                        !inferenceContext.free(uv.getBounds(InferenceBound.UPPER)))) {
-                    maximizeInst((UndetVar)t, warn);
-                    stuck = false;
-                }
-            }
-            if (inferenceContext.restvars().isEmpty()) {
-                //all variables have been instantiated - exit
-                break;
-            } else if (stuck) {
-                //some variables could not be instantiated because of cycles in
-                //upper bounds - provide a (possibly recursive) default instantiation
-                instantiateAsUninferredVars(inferenceContext);
-                break;
-            } else {
-                //some variables have been instantiated - replace newly instantiated
-                //variables in remaining upper bounds and continue
-                for (Type t : inferenceContext.undetvars) {
-                    UndetVar uv = (UndetVar)t;
-                    uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
-                }
-            }
-        }
-    }
-
-    /**
-     * Infer cyclic inference variables as described in 15.12.2.8.
-     */
-    private void instantiateAsUninferredVars(InferenceContext inferenceContext) {
-        ListBuffer<Type> todo = ListBuffer.lb();
-        //step 1 - create fresh tvars
-        for (Type t : inferenceContext.undetvars) {
-            UndetVar uv = (UndetVar)t;
-            if (uv.inst == null) {
-                TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
-                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
-                todo.append(uv);
-                uv.inst = fresh_tvar.type;
-            }
-        }
-        //step 2 - replace fresh tvars in their bounds
-        List<Type> formals = inferenceContext.inferenceVars();
-        for (Type t : todo) {
-            UndetVar uv = (UndetVar)t;
-            TypeVar ct = (TypeVar)uv.inst;
-            ct.bound = types.glb(inferenceContext.asInstTypes(types.getBounds(ct), types));
-            if (ct.bound.isErroneous()) {
-                //report inference error if glb fails
-                reportBoundError(uv, BoundErrorKind.BAD_UPPER);
-            }
-            formals = formals.tail;
-        }
-    }
-
-    /** Instantiate a generic method type by finding instantiations for all its
-     * inference variables so that it can be applied to a given argument type list.
+     * Main inference entry point - instantiate a generic method type
+     * using given argument types and (possibly) an expected target-type.
      */
     public Type instantiateMethod(Env<AttrContext> env,
                                   List<Type> tvars,
@@ -265,259 +146,146 @@
                                   Resolve.MethodCheck methodCheck,
                                   Warner warn) throws InferenceException {
         //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG
-        final InferenceContext inferenceContext = new InferenceContext(tvars, this, true);
+        final InferenceContext inferenceContext = new InferenceContext(tvars);
         inferenceException.clear();
+        try {
+            DeferredAttr.DeferredAttrContext deferredAttrContext =
+                    resolveContext.deferredAttrContext(msym, inferenceContext, resultInfo, warn);
 
-        DeferredAttr.DeferredAttrContext deferredAttrContext =
-                resolveContext.deferredAttrContext(msym, inferenceContext);
+            methodCheck.argumentsAcceptable(env, deferredAttrContext,
+                    argtypes, mt.getParameterTypes(), warn);
 
-        try {
-            methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn);
-
-            if (resultInfo != null && allowEarlyReturnConstraints &&
+            if (allowGraphInference &&
+                    resultInfo != null &&
                     !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
-                generateReturnConstraints(mt, inferenceContext, resultInfo);
+                //inject return constraints earlier
+                checkWithinBounds(inferenceContext, warn); //propagation
+                generateReturnConstraints(resultInfo, mt, inferenceContext);
+                //propagate outwards if needed
+                if (resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
+                    //propagate inference context outwards and exit
+                    inferenceContext.dupTo(resultInfo.checkContext.inferenceContext());
+                    deferredAttrContext.complete();
+                    return mt;
+                }
             }
 
             deferredAttrContext.complete();
 
             // minimize as yet undetermined type variables
-            for (Type t : inferenceContext.undetvars) {
-                minimizeInst((UndetVar)t, warn);
+            if (allowGraphInference) {
+                inferenceContext.solve(warn);
+            } else {
+                inferenceContext.solveLegacy(true, warn, LegacyInferenceSteps.EQ_LOWER.steps); //minimizeInst
             }
 
-            checkWithinBounds(inferenceContext, warn);
+            mt = (MethodType)inferenceContext.asInstType(mt);
 
-            mt = (MethodType)inferenceContext.asInstType(mt, types);
+            if (!allowGraphInference &&
+                    inferenceContext.restvars().nonEmpty() &&
+                    resultInfo != null &&
+                    !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+                generateReturnConstraints(resultInfo, mt, inferenceContext);
+                inferenceContext.solveLegacy(false, warn, LegacyInferenceSteps.EQ_UPPER.steps); //maximizeInst
+                mt = (MethodType)inferenceContext.asInstType(mt);
+            }
 
-            List<Type> restvars = inferenceContext.restvars();
-
-            if (!restvars.isEmpty()) {
-                if (resultInfo != null && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
-                    if (!allowEarlyReturnConstraints) {
-                        generateReturnConstraints(mt, inferenceContext, resultInfo);
-                    }
-                    instantiateUninferred(env.tree.pos(), inferenceContext, mt, resultInfo, warn);
-                    checkWithinBounds(inferenceContext, warn);
-                    mt = (MethodType)inferenceContext.asInstType(mt, types);
-                    if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
-                        log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt);
-                    }
-                }
+            if (resultInfo != null && rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) {
+                log.note(env.tree.pos, "deferred.method.inst", msym, mt, resultInfo.pt);
             }
 
             // return instantiated version of method type
             return mt;
         } finally {
-            inferenceContext.notifyChange(types);
-        }
-    }
-    //where
-        void generateReturnConstraints(Type mt, InferenceContext inferenceContext, Attr.ResultInfo resultInfo) {
-            if (resultInfo != null) {
-                Type to = resultInfo.pt;
-                if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
-                    to = mt.getReturnType().isPrimitiveOrVoid() ?
-                            mt.getReturnType() : syms.objectType;
-                }
-                Type qtype1 = inferenceContext.asFree(mt.getReturnType(), types);
-                Warner retWarn = new Warner();
-                if (!resultInfo.checkContext.compatible(qtype1, qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to, retWarn) ||
-                        //unchecked conversion is not allowed
-                        retWarn.hasLint(Lint.LintCategory.UNCHECKED)) {
-                    throw inferenceException
-                            .setMessage("infer.no.conforming.instance.exists",
-                            inferenceContext.restvars(), mt.getReturnType(), to);
-                }
-            }
-        }
-
-    /** check that type parameters are within their bounds.
-     */
-    void checkWithinBounds(InferenceContext inferenceContext,
-                           Warner warn) throws InferenceException {
-        //step 1 - check compatibility of instantiated type w.r.t. initial bounds
-        for (Type t : inferenceContext.undetvars) {
-            UndetVar uv = (UndetVar)t;
-            uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), types);
-            checkCompatibleUpperBounds(uv, inferenceContext.inferenceVars());
-            if (!inferenceContext.restvars().contains(uv.qtype)) {
-                Type inst = inferenceContext.asInstType(t, types);
-                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
-                    if (!types.isSubtypeUnchecked(inst, inferenceContext.asFree(u, types), warn)) {
-                        reportBoundError(uv, BoundErrorKind.UPPER);
-                    }
-                }
-                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
-                    Assert.check(!inferenceContext.free(l));
-                    if (!types.isSubtypeUnchecked(l, inst, warn)) {
-                        reportBoundError(uv, BoundErrorKind.LOWER);
-                    }
-                }
-                for (Type e : uv.getBounds(InferenceBound.EQ)) {
-                    Assert.check(!inferenceContext.free(e));
-                    if (!types.isSameType(inst, e)) {
-                        reportBoundError(uv, BoundErrorKind.EQ);
-                    }
-                }
-            }
-        }
-
-        //step 2 - check that eq bounds are consistent w.r.t. eq/lower bounds
-        for (Type t : inferenceContext.undetvars) {
-            UndetVar uv = (UndetVar)t;
-            //check eq bounds consistency
-            Type eq = null;
-            for (Type e : uv.getBounds(InferenceBound.EQ)) {
-                Assert.check(!inferenceContext.free(e));
-                if (eq != null && !types.isSameType(e, eq)) {
-                    reportBoundError(uv, BoundErrorKind.EQ);
-                }
-                eq = e;
-                for (Type l : uv.getBounds(InferenceBound.LOWER)) {
-                    Assert.check(!inferenceContext.free(l));
-                    if (!types.isSubtypeUnchecked(l, e, warn)) {
-                        reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
-                    }
-                }
-                for (Type u : uv.getBounds(InferenceBound.UPPER)) {
-                    if (inferenceContext.free(u)) continue;
-                    if (!types.isSubtypeUnchecked(e, u, warn)) {
-                        reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
-                    }
-                }
+            if (resultInfo != null || !allowGraphInference) {
+                inferenceContext.notifyChange();
+            } else {
+                inferenceContext.notifyChange(inferenceContext.boundedVars());
             }
         }
     }
 
-    void checkCompatibleUpperBounds(UndetVar uv, List<Type> tvars) {
-        // VGJ: sort of inlined maximizeInst() below.  Adding
-        // bounds can cause lobounds that are above hibounds.
-        ListBuffer<Type> hiboundsNoVars = ListBuffer.lb();
-        for (Type t : Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter)) {
-            if (!t.containsAny(tvars)) {
-                hiboundsNoVars.append(t);
+    /**
+     * Generate constraints from the generic method's return type. If the method
+     * call occurs in a context where a type T is expected, use the expected
+     * type to derive more constraints on the generic method inference variables.
+     */
+    void generateReturnConstraints(Attr.ResultInfo resultInfo,
+            MethodType mt, InferenceContext inferenceContext) {
+        Type qtype1 = inferenceContext.asFree(mt.getReturnType());
+        Type to = returnConstraintTarget(qtype1, resultInfo.pt);
+        Assert.check(allowGraphInference || !resultInfo.checkContext.inferenceContext().free(to),
+                "legacy inference engine cannot handle constraints on both sides of a subtyping assertion");
+        //we need to skip capture?
+        Warner retWarn = new Warner();
+        if (!resultInfo.checkContext.compatible(qtype1, resultInfo.checkContext.inferenceContext().asFree(to), retWarn) ||
+                //unchecked conversion is not allowed
+                retWarn.hasLint(Lint.LintCategory.UNCHECKED)) {
+            throw inferenceException
+                    .setMessage("infer.no.conforming.instance.exists",
+                    inferenceContext.restvars(), mt.getReturnType(), to);
+        }
+    }
+    //where
+        private Type returnConstraintTarget(Type from, Type to) {
+            if (from.hasTag(VOID)) {
+                return syms.voidType;
+            } else if (to.hasTag(NONE)) {
+                return from.isPrimitive() ? from : syms.objectType;
+            } else if (from.hasTag(UNDETVAR) && to.isPrimitive()) {
+                if (!allowGraphInference) {
+                    //if legacy, just return boxed type
+                    return types.boxedClass(to).type;
+                }
+                //if graph inference we need to skip conflicting boxed bounds...
+                UndetVar uv = (UndetVar)from;
+                for (Type t : uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)) {
+                    Type boundAsPrimitive = types.unboxedType(t);
+                    if (boundAsPrimitive == null) continue;
+                    if (types.isConvertible(boundAsPrimitive, to)) {
+                        //effectively skip return-type constraint generation (compatibility)
+                        return syms.objectType;
+                    }
+                }
+                return types.boxedClass(to).type;
+            } else {
+                return to;
             }
         }
-        List<Type> hibounds = hiboundsNoVars.toList();
-        Type hb = null;
-        if (hibounds.isEmpty())
-            hb = syms.objectType;
-        else if (hibounds.tail.isEmpty())
-            hb = hibounds.head;
-        else
-            hb = types.glb(hibounds);
-        if (hb == null || hb.isErroneous())
-            reportBoundError(uv, BoundErrorKind.BAD_UPPER);
-    }
 
-    enum BoundErrorKind {
-        BAD_UPPER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("incompatible.upper.bounds", uv.qtype,
-                        uv.getBounds(InferenceBound.UPPER));
+    /**
+      * Infer cyclic inference variables as described in 15.12.2.8.
+      */
+    private void instantiateAsUninferredVars(List<Type> vars, InferenceContext inferenceContext) {
+        ListBuffer<Type> todo = ListBuffer.lb();
+        //step 1 - create fresh tvars
+        for (Type t : vars) {
+            UndetVar uv = (UndetVar)inferenceContext.asFree(t);
+            List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
+            if (Type.containsAny(upperBounds, vars)) {
+                TypeSymbol fresh_tvar = new TypeSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
+                fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
+                todo.append(uv);
+                uv.inst = fresh_tvar.type;
+            } else if (upperBounds.nonEmpty()) {
+                uv.inst = types.glb(upperBounds);
+            } else {
+                uv.inst = syms.objectType;
             }
-        },
-        BAD_EQ_UPPER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype,
-                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER));
+        }
+        //step 2 - replace fresh tvars in their bounds
+        List<Type> formals = vars;
+        for (Type t : todo) {
+            UndetVar uv = (UndetVar)t;
+            TypeVar ct = (TypeVar)uv.inst;
+            ct.bound = types.glb(inferenceContext.asInstTypes(types.getBounds(ct)));
+            if (ct.bound.isErroneous()) {
+                //report inference error if glb fails
+                reportBoundError(uv, BoundErrorKind.BAD_UPPER);
             }
-        },
-        BAD_EQ_LOWER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype,
-                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER));
-            }
-        },
-        UPPER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst,
-                        uv.getBounds(InferenceBound.UPPER));
-            }
-        },
-        LOWER() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst,
-                        uv.getBounds(InferenceBound.LOWER));
-            }
-        },
-        EQ() {
-            @Override
-            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
-                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst,
-                        uv.getBounds(InferenceBound.EQ));
-            }
-        };
-
-        abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv);
-    }
-    //where
-    void reportBoundError(UndetVar uv, BoundErrorKind bk) {
-        throw bk.setMessage(inferenceException, uv);
-    }
-
-    // <editor-fold desc="functional interface instantiation">
-    /**
-     * This method is used to infer a suitable target functional interface in case
-     * the original parameterized interface contains wildcards. An inference process
-     * is applied so that wildcard bounds, as well as explicit lambda/method ref parameters
-     * (where applicable) are used to constraint the solution.
-     */
-    public Type instantiateFunctionalInterface(DiagnosticPosition pos, Type funcInterface,
-            List<Type> paramTypes, Check.CheckContext checkContext) {
-        if (types.capture(funcInterface) == funcInterface) {
-            //if capture doesn't change the type then return the target unchanged
-            //(this means the target contains no wildcards!)
-            return funcInterface;
-        } else {
-            Type formalInterface = funcInterface.tsym.type;
-            InferenceContext funcInterfaceContext =
-                    new InferenceContext(funcInterface.tsym.type.getTypeArguments(), this, false);
-            Assert.check(paramTypes != null);
-            //get constraints from explicit params (this is done by
-            //checking that explicit param types are equal to the ones
-            //in the functional interface descriptors)
-            List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
-            if (descParameterTypes.size() != paramTypes.size()) {
-                checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
-                return types.createErrorType(funcInterface);
-            }
-            for (Type p : descParameterTypes) {
-                if (!types.isSameType(funcInterfaceContext.asFree(p, types), paramTypes.head)) {
-                    checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
-                    return types.createErrorType(funcInterface);
-                }
-                paramTypes = paramTypes.tail;
-            }
-            List<Type> actualTypeargs = funcInterface.getTypeArguments();
-            for (Type t : funcInterfaceContext.undetvars) {
-                UndetVar uv = (UndetVar)t;
-                minimizeInst(uv, types.noWarnings);
-                if (uv.inst == null &&
-                        Type.filter(uv.getBounds(InferenceBound.UPPER), boundFilter).nonEmpty()) {
-                    maximizeInst(uv, types.noWarnings);
-                }
-                if (uv.inst == null) {
-                    uv.inst = actualTypeargs.head;
-                }
-                actualTypeargs = actualTypeargs.tail;
-            }
-            Type owntype = funcInterfaceContext.asInstType(formalInterface, types);
-            if (!chk.checkValidGenericType(owntype)) {
-                //if the inferred functional interface type is not well-formed,
-                //or if it's not a subtype of the original target, issue an error
-                checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
-            }
-            return owntype;
+            formals = formals.tail;
         }
     }
-    // </editor-fold>
 
     /**
      * Compute a synthetic method type corresponding to the requested polymorphic
@@ -571,7 +339,7 @@
         class ImplicitArgType extends DeferredAttr.DeferredTypeMap {
 
             public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) {
-                deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
+                rs.deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
             }
 
             public Type apply(Type t) {
@@ -585,23 +353,927 @@
         }
 
     /**
-     * Mapping that turns inference variables into undet vars
-     * (used by inference context)
+      * This method is used to infer a suitable target SAM in case the original
+      * SAM type contains one or more wildcards. An inference process is applied
+      * so that wildcard bounds, as well as explicit lambda/method ref parameters
+      * (where applicable) are used to constraint the solution.
+      */
+    public Type instantiateFunctionalInterface(DiagnosticPosition pos, Type funcInterface,
+            List<Type> paramTypes, Check.CheckContext checkContext) {
+        if (types.capture(funcInterface) == funcInterface) {
+            //if capture doesn't change the type then return the target unchanged
+            //(this means the target contains no wildcards!)
+            return funcInterface;
+        } else {
+            Type formalInterface = funcInterface.tsym.type;
+            InferenceContext funcInterfaceContext =
+                    new InferenceContext(funcInterface.tsym.type.getTypeArguments());
+
+            Assert.check(paramTypes != null);
+            //get constraints from explicit params (this is done by
+            //checking that explicit param types are equal to the ones
+            //in the functional interface descriptors)
+            List<Type> descParameterTypes = types.findDescriptorType(formalInterface).getParameterTypes();
+            if (descParameterTypes.size() != paramTypes.size()) {
+                checkContext.report(pos, diags.fragment("incompatible.arg.types.in.lambda"));
+                return types.createErrorType(funcInterface);
+            }
+            for (Type p : descParameterTypes) {
+                if (!types.isSameType(funcInterfaceContext.asFree(p), paramTypes.head)) {
+                    checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
+                    return types.createErrorType(funcInterface);
+                }
+                paramTypes = paramTypes.tail;
+            }
+
+            try {
+                funcInterfaceContext.solve(funcInterfaceContext.boundedVars(), types.noWarnings);
+            } catch (InferenceException ex) {
+                checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
+            }
+
+            List<Type> actualTypeargs = funcInterface.getTypeArguments();
+            for (Type t : funcInterfaceContext.undetvars) {
+                UndetVar uv = (UndetVar)t;
+                if (uv.inst == null) {
+                    uv.inst = actualTypeargs.head;
+                }
+                actualTypeargs = actualTypeargs.tail;
+            }
+
+            Type owntype = funcInterfaceContext.asInstType(formalInterface);
+            if (!chk.checkValidGenericType(owntype)) {
+                //if the inferred functional interface type is not well-formed,
+                //or if it's not a subtype of the original target, issue an error
+                checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
+            }
+            return owntype;
+        }
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Bound checking">
+    /**
+     * Check bounds and perform incorporation
      */
-    class FromTypeVarFun extends Mapping {
+    void checkWithinBounds(InferenceContext inferenceContext,
+                             Warner warn) throws InferenceException {
+        MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars);
+        try {
+            while (true) {
+                mlistener.reset();
+                if (!allowGraphInference) {
+                    //in legacy mode we lack of transitivity, so bound check
+                    //cannot be run in parallel with other incoprporation rounds
+                    for (Type t : inferenceContext.undetvars) {
+                        UndetVar uv = (UndetVar)t;
+                        IncorporationStep.CHECK_BOUNDS.apply(uv, inferenceContext, warn);
+                    }
+                }
+                for (Type t : inferenceContext.undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    //bound incorporation
+                    EnumSet<IncorporationStep> incorporationSteps = allowGraphInference ?
+                            incorporationStepsGraph : incorporationStepsLegacy;
+                    for (IncorporationStep is : incorporationSteps) {
+                        is.apply(uv, inferenceContext, warn);
+                    }
+                }
+                if (!mlistener.changed || !allowGraphInference) break;
+            }
+        }
+        finally {
+            mlistener.detach();
+        }
+    }
+    //where
+        /**
+         * This listener keeps track of changes on a group of inference variable
+         * bounds. Note: the listener must be detached (calling corresponding
+         * method) to make sure that the underlying inference variable is
+         * left in a clean state.
+         */
+        class MultiUndetVarListener implements UndetVar.UndetVarListener {
 
-        boolean includeBounds;
+            int rounds;
+            boolean changed;
+            List<Type> undetvars;
 
-        FromTypeVarFun(boolean includeBounds) {
-            super("fromTypeVarFunWithBounds");
-            this.includeBounds = includeBounds;
+            public MultiUndetVarListener(List<Type> undetvars) {
+                this.undetvars = undetvars;
+                for (Type t : undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    uv.listener = this;
+                }
+            }
+
+            public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
+                //avoid non-termination
+                if (rounds < MAX_INCORPORATION_STEPS) {
+                    changed = true;
+                }
+            }
+
+            void reset() {
+                rounds++;
+                changed = false;
+            }
+
+            void detach() {
+                for (Type t : undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    uv.listener = null;
+                }
+            }
+        };
+
+        /** max number of incorporation rounds */
+        static final int MAX_INCORPORATION_STEPS = 100;
+
+    /**
+     * This enumeration defines an entry point for doing inference variable
+     * bound incorporation - it can be used to inject custom incorporation
+     * logic into the basic bound checking routine
+     */
+    enum IncorporationStep {
+        /**
+         * Performs basic bound checking - i.e. is the instantiated type for a given
+         * inference variable compatible with its bounds?
+         */
+        CHECK_BOUNDS() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                uv.substBounds(inferenceContext.inferenceVars(), inferenceContext.instTypes(), infer.types);
+                infer.checkCompatibleUpperBounds(uv, inferenceContext);
+                if (uv.inst != null) {
+                    Type inst = uv.inst;
+                    for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                        if (!infer.types.isSubtypeUnchecked(inst, inferenceContext.asFree(u), warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.UPPER);
+                        }
+                    }
+                    for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), inst, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.LOWER);
+                        }
+                    }
+                    for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                        if (!infer.types.isSameType(inst, inferenceContext.asFree(e))) {
+                            infer.reportBoundError(uv, BoundErrorKind.EQ);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Check consistency of equality constraints. This is a slightly more aggressive
+         * inference routine that is designed as to maximize compatibility with JDK 7.
+         * Note: this is not used in graph mode.
+         */
+        EQ_CHECK_LEGACY() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                Type eq = null;
+                for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                    Assert.check(!inferenceContext.free(e));
+                    if (eq != null && !infer.types.isSameType(e, eq)) {
+                        infer.reportBoundError(uv, BoundErrorKind.EQ);
+                    }
+                    eq = e;
+                    for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                        Assert.check(!inferenceContext.free(l));
+                        if (!infer.types.isSubtypeUnchecked(l, e, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
+                        }
+                    }
+                    for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                        if (inferenceContext.free(u)) continue;
+                        if (!infer.types.isSubtypeUnchecked(e, u, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Check consistency of equality constraints.
+         */
+        EQ_CHECK() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type e : uv.getBounds(InferenceBound.EQ)) {
+                    if (e.containsAny(inferenceContext.inferenceVars())) continue;
+                    for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                        if (!infer.types.isSubtypeUnchecked(e, inferenceContext.asFree(u), warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_UPPER);
+                        }
+                    }
+                    for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!infer.types.isSubtypeUnchecked(inferenceContext.asFree(l), e, warn)) {
+                            infer.reportBoundError(uv, BoundErrorKind.BAD_EQ_LOWER);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha <: T} and {@code alpha :> S}
+         * perform {@code S <: T} (which could lead to new bounds).
+         */
+        CROSS_UPPER_LOWER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
+                    for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!inferenceContext.inferenceVars().contains(b1) &&
+                                !inferenceContext.inferenceVars().contains(b2) &&
+                                infer.types.asSuper(b2, b1.tsym) != null) {
+                            infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha <: T} and {@code alpha == S}
+         * perform {@code S <: T} (which could lead to new bounds).
+         */
+        CROSS_UPPER_EQ() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b1 : uv.getBounds(InferenceBound.UPPER)) {
+                    for (Type b2 : uv.getBounds(InferenceBound.EQ)) {
+                        if (!inferenceContext.inferenceVars().contains(b1) &&
+                                !inferenceContext.inferenceVars().contains(b2) &&
+                                infer.types.asSuper(b2, b1.tsym) != null) {
+                            infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha :> S} and {@code alpha == T}
+         * perform {@code S <: T} (which could lead to new bounds).
+         */
+        CROSS_EQ_LOWER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b1 : uv.getBounds(InferenceBound.EQ)) {
+                    for (Type b2 : uv.getBounds(InferenceBound.LOWER)) {
+                        if (!inferenceContext.inferenceVars().contains(b1) &&
+                                !inferenceContext.inferenceVars().contains(b2) &&
+                                infer.types.asSuper(b2, b1.tsym) != null) {
+                            infer.types.isSubtypeUnchecked(inferenceContext.asFree(b2), inferenceContext.asFree(b1));
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha <: beta} propagate lower bounds
+         * from alpha to beta; also propagate upper bounds from beta to alpha.
+         */
+        PROP_UPPER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b : uv.getBounds(InferenceBound.UPPER)) {
+                    if (inferenceContext.inferenceVars().contains(b)) {
+                        UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
+                        //alpha <: beta
+                        //1. copy alpha's lower to beta's
+                        for (Type l : uv.getBounds(InferenceBound.LOWER)) {
+                            uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
+                        }
+                        //2. copy beta's upper to alpha's
+                        for (Type u : uv2.getBounds(InferenceBound.UPPER)) {
+                            uv.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha :> beta} propagate lower bounds
+         * from beta to alpha; also propagate upper bounds from alpha to beta.
+         */
+        PROP_LOWER() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b : uv.getBounds(InferenceBound.LOWER)) {
+                    if (inferenceContext.inferenceVars().contains(b)) {
+                        UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
+                        //alpha :> beta
+                        //1. copy alpha's upper to beta's
+                        for (Type u : uv.getBounds(InferenceBound.UPPER)) {
+                            uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types);
+                        }
+                        //2. copy beta's lower to alpha's
+                        for (Type l : uv2.getBounds(InferenceBound.LOWER)) {
+                            uv.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types);
+                        }
+                    }
+                }
+            }
+        },
+        /**
+         * Given a bound set containing {@code alpha == beta} propagate lower/upper
+         * bounds from alpha to beta and back.
+         */
+        PROP_EQ() {
+            public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) {
+                Infer infer = inferenceContext.infer();
+                for (Type b : uv.getBounds(InferenceBound.EQ)) {
+                    if (inferenceContext.inferenceVars().contains(b)) {
+                        UndetVar uv2 = (UndetVar)inferenceContext.asFree(b);
+                        //alpha == beta
+                        //1. copy all alpha's bounds to beta's
+                        for (InferenceBound ib : InferenceBound.values()) {
+                            for (Type b2 : uv.getBounds(ib)) {
+                                if (b2 != uv2) {
+                                    uv2.addBound(ib, inferenceContext.asInstType(b2), infer.types);
+                                }
+                            }
+                        }
+                        //2. copy all beta's bounds to alpha's
+                        for (InferenceBound ib : InferenceBound.values()) {
+                            for (Type b2 : uv2.getBounds(ib)) {
+                                if (b2 != uv) {
+                                    uv.addBound(ib, inferenceContext.asInstType(b2), infer.types);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        };
+
+        abstract void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn);
+    }
+
+    /** incorporation steps to be executed when running in legacy mode */
+    EnumSet<IncorporationStep> incorporationStepsLegacy = EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY);
+
+    /** incorporation steps to be executed when running in graph mode */
+    EnumSet<IncorporationStep> incorporationStepsGraph =
+            EnumSet.complementOf(EnumSet.of(IncorporationStep.EQ_CHECK_LEGACY));
+
+    /**
+     * Make sure that the upper bounds we got so far lead to a solvable inference
+     * variable by making sure that a glb exists.
+     */
+    void checkCompatibleUpperBounds(UndetVar uv, InferenceContext inferenceContext) {
+        List<Type> hibounds =
+                Type.filter(uv.getBounds(InferenceBound.UPPER), new BoundFilter(inferenceContext));
+        Type hb = null;
+        if (hibounds.isEmpty())
+            hb = syms.objectType;
+        else if (hibounds.tail.isEmpty())
+            hb = hibounds.head;
+        else
+            hb = types.glb(hibounds);
+        if (hb == null || hb.isErroneous())
+            reportBoundError(uv, BoundErrorKind.BAD_UPPER);
+    }
+    //where
+        protected static class BoundFilter implements Filter<Type> {
+
+            InferenceContext inferenceContext;
+
+            public BoundFilter(InferenceContext inferenceContext) {
+                this.inferenceContext = inferenceContext;
+            }
+
+            @Override
+            public boolean accepts(Type t) {
+                return !t.isErroneous() && !inferenceContext.free(t) &&
+                        !t.hasTag(BOT);
+            }
+        };
+
+    /**
+     * This enumeration defines all possible bound-checking related errors.
+     */
+    enum BoundErrorKind {
+        /**
+         * The (uninstantiated) inference variable has incompatible upper bounds.
+         */
+        BAD_UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.upper.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        /**
+         * An equality constraint is not compatible with an upper bound.
+         */
+        BAD_EQ_UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.eq.upper.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        /**
+         * An equality constraint is not compatible with a lower bound.
+         */
+        BAD_EQ_LOWER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("incompatible.eq.lower.bounds", uv.qtype,
+                        uv.getBounds(InferenceBound.EQ), uv.getBounds(InferenceBound.LOWER));
+            }
+        },
+        /**
+         * Instantiated inference variable is not compatible with an upper bound.
+         */
+        UPPER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.upper.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.UPPER));
+            }
+        },
+        /**
+         * Instantiated inference variable is not compatible with a lower bound.
+         */
+        LOWER() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.lower.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.LOWER));
+            }
+        },
+        /**
+         * Instantiated inference variable is not compatible with an equality constraint.
+         */
+        EQ() {
+            @Override
+            InapplicableMethodException setMessage(InferenceException ex, UndetVar uv) {
+                return ex.setMessage("inferred.do.not.conform.to.eq.bounds", uv.inst,
+                        uv.getBounds(InferenceBound.EQ));
+            }
+        };
+
+        abstract InapplicableMethodException setMessage(InferenceException ex, UndetVar uv);
+    }
+
+    /**
+     * Report a bound-checking error of given kind
+     */
+    void reportBoundError(UndetVar uv, BoundErrorKind bk) {
+        throw bk.setMessage(inferenceException, uv);
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Inference engine">
+    /**
+     * Graph inference strategy - act as an input to the inference solver; a strategy is
+     * composed of two ingredients: (i) find a node to solve in the inference graph,
+     * and (ii) tell th engine when we are done fixing inference variables
+     */
+    interface GraphStrategy {
+        /**
+         * Pick the next node (leaf) to solve in the graph
+         */
+        Node pickNode(InferenceGraph g);
+        /**
+         * Is this the last step?
+         */
+        boolean done();
+    }
+
+    /**
+     * Simple solver strategy class that locates all leaves inside a graph
+     * and picks the first leaf as the next node to solve
+     */
+    abstract class LeafSolver implements GraphStrategy {
+        public Node pickNode(InferenceGraph g) {
+                        Assert.check(!g.nodes.isEmpty(), "No nodes to solve!");
+            return g.nodes.get(0);
+        }
+    }
+
+    /**
+     * This solver uses an heuristic to pick the best leaf - the heuristic
+     * tries to select the node that has maximal probability to contain one
+     * or more inference variables in a given list
+     */
+    abstract class BestLeafSolver extends LeafSolver {
+
+        List<Type> varsToSolve;
+
+        BestLeafSolver(List<Type> varsToSolve) {
+            this.varsToSolve = varsToSolve;
         }
 
-        public Type apply(Type t) {
-            if (t.hasTag(TYPEVAR)) return new UndetVar((TypeVar)t, types, includeBounds);
-            else return t.map(this);
+        /**
+         * Computes the cost associated with a given node; the cost is computed
+         * as the total number of type-variables that should be eagerly instantiated
+         * in order to get to some of the variables in {@code varsToSolve} from
+         * a given node
+         */
+        void computeCostIfNeeded(Node n, Map<Node, Integer> costMap) {
+            if (costMap.containsKey(n)) {
+                return;
+            } else if (!Collections.disjoint(n.data, varsToSolve)) {
+                costMap.put(n, n.data.size());
+            } else {
+                int subcost = Integer.MAX_VALUE;
+                costMap.put(n, subcost); //avoid loops
+                for (Node n2 : n.getDependencies()) {
+                    computeCostIfNeeded(n2, costMap);
+                    subcost = Math.min(costMap.get(n2), subcost);
+                }
+                //update cost map to reflect real cost
+                costMap.put(n, subcost == Integer.MAX_VALUE ?
+                        Integer.MAX_VALUE :
+                        n.data.size() + subcost);
+            }
         }
-    };
+
+        /**
+         * Pick the leaf that minimize cost
+         */
+        @Override
+        public Node pickNode(final InferenceGraph g) {
+            final Map<Node, Integer> costMap = new HashMap<Node, Integer>();
+            ArrayList<Node> leaves = new ArrayList<Node>();
+            for (Node n : g.nodes) {
+                computeCostIfNeeded(n, costMap);
+                if (n.isLeaf(n)) {
+                    leaves.add(n);
+                }
+            }
+            Assert.check(!leaves.isEmpty(), "No nodes to solve!");
+            Collections.sort(leaves, new java.util.Comparator<Node>() {
+                public int compare(Node n1, Node n2) {
+                    return costMap.get(n1) - costMap.get(n2);
+                }
+            });
+            return leaves.get(0);
+        }
+    }
+
+    /**
+     * The inference process can be thought of as a sequence of steps. Each step
+     * instantiates an inference variable using a subset of the inference variable
+     * bounds, if certain condition are met. Decisions such as the sequence in which
+     * steps are applied, or which steps are to be applied are left to the inference engine.
+     */
+    enum InferenceStep {
+
+        /**
+         * Instantiate an inference variables using one of its (ground) equality
+         * constraints
+         */
+        EQ(InferenceBound.EQ) {
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                return filterBounds(uv, inferenceContext).head;
+            }
+        },
+        /**
+         * Instantiate an inference variables using its (ground) lower bounds. Such
+         * bounds are merged together using lub().
+         */
+        LOWER(InferenceBound.LOWER) {
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                Infer infer = inferenceContext.infer();
+                List<Type> lobounds = filterBounds(uv, inferenceContext);
+                Type owntype = infer.types.lub(lobounds);
+                if (owntype.hasTag(ERROR)) {
+                    throw infer.inferenceException
+                        .setMessage("no.unique.minimal.instance.exists",
+                                    uv.qtype, lobounds);
+                } else {
+                    return owntype;
+                }
+            }
+        },
+        /**
+         * Instantiate an inference variables using its (ground) upper bounds. Such
+         * bounds are merged together using glb().
+         */
+        UPPER(InferenceBound.UPPER) {
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                Infer infer = inferenceContext.infer();
+                List<Type> hibounds = filterBounds(uv, inferenceContext);
+                Type owntype = infer.types.glb(hibounds);
+                if (owntype.isErroneous()) {
+                    throw infer.inferenceException
+                        .setMessage("no.unique.maximal.instance.exists",
+                                    uv.qtype, hibounds);
+                } else {
+                    return owntype;
+                }
+            }
+        },
+        /**
+         * Like the former; the only difference is that this step can only be applied
+         * if all upper bounds are ground.
+         */
+        UPPER_LEGACY(InferenceBound.UPPER) {
+            @Override
+            public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
+                return !inferenceContext.free(t.getBounds(ib));
+            }
+
+            @Override
+            Type solve(UndetVar uv, InferenceContext inferenceContext) {
+                return UPPER.solve(uv, inferenceContext);
+            }
+        };
+
+        final InferenceBound ib;
+
+        InferenceStep(InferenceBound ib) {
+            this.ib = ib;
+        }
+
+        /**
+         * Find an instantiated type for a given inference variable within
+         * a given inference context
+         */
+        abstract Type solve(UndetVar uv, InferenceContext inferenceContext);
+
+        /**
+         * Can the inference variable be instantiated using this step?
+         */
+        public boolean accepts(UndetVar t, InferenceContext inferenceContext) {
+            return filterBounds(t, inferenceContext).nonEmpty();
+        }
+
+        /**
+         * Return the subset of ground bounds in a given bound set (i.e. eq/lower/upper)
+         */
+        List<Type> filterBounds(UndetVar uv, InferenceContext inferenceContext) {
+            return Type.filter(uv.getBounds(ib), new BoundFilter(inferenceContext));
+        }
+    }
+
+    /**
+     * This enumeration defines the sequence of steps to be applied when the
+     * solver works in legacy mode. The steps in this enumeration reflect
+     * the behavior of old inference routine (see JLS SE 7 15.12.2.7/15.12.2.8).
+     */
+    enum LegacyInferenceSteps {
+
+        EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)),
+        EQ_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.UPPER_LEGACY));
+
+        final EnumSet<InferenceStep> steps;
+
+        LegacyInferenceSteps(EnumSet<InferenceStep> steps) {
+            this.steps = steps;
+        }
+    }
+
+    /**
+     * This enumeration defines the sequence of steps to be applied when the
+     * graph solver is used. This order is defined so as to maximize compatibility
+     * w.r.t. old inference routine (see JLS SE 7 15.12.2.7/15.12.2.8).
+     */
+    enum GraphInferenceSteps {
+
+        EQ(EnumSet.of(InferenceStep.EQ)),
+        EQ_LOWER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER)),
+        EQ_LOWER_UPPER(EnumSet.of(InferenceStep.EQ, InferenceStep.LOWER, InferenceStep.UPPER));
+
+        final EnumSet<InferenceStep> steps;
+
+        GraphInferenceSteps(EnumSet<InferenceStep> steps) {
+            this.steps = steps;
+        }
+    }
+
+    /**
+     * This is the graph inference solver - the solver organizes all inference variables in
+     * a given inference context by bound dependencies - in the general case, such dependencies
+     * would lead to a cyclic directed graph (hence the name); the dependency info is used to build
+     * an acyclic graph, where all cyclic variables are bundled together. An inference
+     * step corresponds to solving a node in the acyclic graph - this is done by
+     * relying on a given strategy (see GraphStrategy).
+     */
+    class GraphSolver {
+
+        InferenceContext inferenceContext;
+        Warner warn;
+
+        GraphSolver(InferenceContext inferenceContext, Warner warn) {
+            this.inferenceContext = inferenceContext;
+            this.warn = warn;
+        }
+
+        /**
+         * Solve variables in a given inference context. The amount of variables
+         * to be solved, and the way in which the underlying acyclic graph is explored
+         * depends on the selected solver strategy.
+         */
+        void solve(GraphStrategy sstrategy) {
+            checkWithinBounds(inferenceContext, warn); //initial propagation of bounds
+            InferenceGraph inferenceGraph = new InferenceGraph();
+            while (!sstrategy.done()) {
+                InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph);
+                List<Type> varsToSolve = List.from(nodeToSolve.data);
+                inferenceContext.save();
+                try {
+                    //repeat until all variables are solved
+                    outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) {
+                        //for each inference phase
+                        for (GraphInferenceSteps step : GraphInferenceSteps.values()) {
+                            if (inferenceContext.solveBasic(varsToSolve, step.steps)) {
+                                checkWithinBounds(inferenceContext, warn);
+                                continue outer;
+                            }
+                        }
+                        //no progress
+                        throw inferenceException;
+                    }
+                }
+                catch (InferenceException ex) {
+                    inferenceContext.rollback();
+                    instantiateAsUninferredVars(varsToSolve, inferenceContext);
+                    checkWithinBounds(inferenceContext, warn);
+                }
+                inferenceGraph.deleteNode(nodeToSolve);
+            }
+        }
+
+        /**
+         * The dependencies between the inference variables that need to be solved
+         * form a (possibly cyclic) graph. This class reduces the original dependency graph
+         * to an acyclic version, where cyclic nodes are folded into a single 'super node'.
+         */
+        class InferenceGraph {
+
+            /**
+             * This class represents a node in the graph. Each node corresponds
+             * to an inference variable and has edges (dependencies) on other
+             * nodes. The node defines an entry point that can be used to receive
+             * updates on the structure of the graph this node belongs to (used to
+             * keep dependencies in sync).
+             */
+            class Node extends GraphUtils.TarjanNode<ListBuffer<Type>> {
+
+                Set<Node> deps;
+
+                Node(Type ivar) {
+                    super(ListBuffer.of(ivar));
+                    this.deps = new HashSet<Node>();
+                }
+
+                @Override
+                public Iterable<? extends Node> getDependencies() {
+                    return deps;
+                }
+
+                @Override
+                public String printDependency(GraphUtils.Node<ListBuffer<Type>> to) {
+                    StringBuilder buf = new StringBuilder();
+                    String sep = "";
+                    for (Type from : data) {
+                        UndetVar uv = (UndetVar)inferenceContext.asFree(from);
+                        for (Type bound : uv.getBounds(InferenceBound.values())) {
+                            if (bound.containsAny(List.from(to.data))) {
+                                buf.append(sep);
+                                buf.append(bound);
+                                sep = ",";
+                            }
+                        }
+                    }
+                    return buf.toString();
+                }
+
+                boolean isLeaf(Node n) {
+                    //no deps, or only one self dep
+                    return (n.deps.isEmpty() ||
+                            n.deps.size() == 1 && n.deps.contains(n));
+                }
+
+                void mergeWith(List<? extends Node> nodes) {
+                    for (Node n : nodes) {
+                        Assert.check(n.data.length() == 1, "Attempt to merge a compound node!");
+                        data.appendList(n.data);
+                        deps.addAll(n.deps);
+                    }
+                    //update deps
+                    Set<Node> deps2 = new HashSet<Node>();
+                    for (Node d : deps) {
+                        if (data.contains(d.data.first())) {
+                            deps2.add(this);
+                        } else {
+                            deps2.add(d);
+                        }
+                    }
+                    deps = deps2;
+                }
+
+                void graphChanged(Node from, Node to) {
+                    if (deps.contains(from)) {
+                        deps.remove(from);
+                        if (to != null) {
+                            deps.add(to);
+                        }
+                    }
+                }
+            }
+
+            /** the nodes in the inference graph */
+            ArrayList<Node> nodes;
+
+            InferenceGraph() {
+                initNodes();
+            }
+
+            /**
+             * Delete a node from the graph. This update the underlying structure
+             * of the graph (including dependencies) via listeners updates.
+             */
+            public void deleteNode(Node n) {
+                Assert.check(nodes.contains(n));
+                nodes.remove(n);
+                notifyUpdate(n, null);
+            }
+
+            /**
+             * Notify all nodes of a change in the graph. If the target node is
+             * {@code null} the source node is assumed to be removed.
+             */
+            void notifyUpdate(Node from, Node to) {
+                for (Node n : nodes) {
+                    n.graphChanged(from, to);
+                }
+            }
+
+            /**
+             * Create the graph nodes. First a simple node is created for every inference
+             * variables to be solved. Then Tarjan is used to found all connected components
+             * in the graph. For each component containing more than one node, a super node is
+                 * created, effectively replacing the original cyclic nodes.
+             */
+            void initNodes() {
+                ArrayList<Node> nodes = new ArrayList<Node>();
+                for (Type t : inferenceContext.restvars()) {
+                    nodes.add(new Node(t));
+                }
+                for (Node n_i : nodes) {
+                    Type i = n_i.data.first();
+                    for (Node n_j : nodes) {
+                        Type j = n_j.data.first();
+                        UndetVar uv_i = (UndetVar)inferenceContext.asFree(i);
+                        if (Type.containsAny(uv_i.getBounds(InferenceBound.values()), List.of(j))) {
+                            //update i's deps
+                            n_i.deps.add(n_j);
+                            //update j's deps - only if i's bounds contain _exactly_ j
+                            if (uv_i.getBounds(InferenceBound.values()).contains(j)) {
+                                n_j.deps.add(n_i);
+                            }
+                        }
+                    }
+                }
+                this.nodes = new ArrayList<Node>();
+                for (List<? extends Node> conSubGraph : GraphUtils.tarjan(nodes)) {
+                    if (conSubGraph.length() > 1) {
+                        Node root = conSubGraph.head;
+                        root.mergeWith(conSubGraph.tail);
+                        for (Node n : conSubGraph) {
+                            notifyUpdate(n, root);
+                        }
+                    }
+                    this.nodes.add(conSubGraph.head);
+                }
+            }
+
+            /**
+             * Debugging: dot representation of this graph
+             */
+            String toDot() {
+                StringBuilder buf = new StringBuilder();
+                for (Type t : inferenceContext.undetvars) {
+                    UndetVar uv = (UndetVar)t;
+                    buf.append(String.format("var %s - upper bounds = %s, lower bounds = %s, eq bounds = %s\\n",
+                            uv.qtype, uv.getBounds(InferenceBound.UPPER), uv.getBounds(InferenceBound.LOWER),
+                            uv.getBounds(InferenceBound.EQ)));
+                }
+                return GraphUtils.toDot(nodes, "inferenceGraph" + hashCode(), buf.toString());
+            }
+        }
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Inference context">
+    /**
+     * Functional interface for defining inference callbacks. Certain actions
+     * (i.e. subtyping checks) might need to be redone after all inference variables
+     * have been fixed.
+     */
+    interface FreeTypeListener {
+        void typesInferred(InferenceContext inferenceContext);
+    }
 
     /**
      * An inference context keeps track of the set of variables that are free
@@ -611,16 +1283,7 @@
      * it can be used as an entry point for performing upper/lower bound inference
      * (see InferenceKind).
      */
-    static class InferenceContext {
-
-        /**
-        * Single-method-interface for defining inference callbacks. Certain actions
-        * (i.e. subtyping checks) might need to be redone after all inference variables
-        * have been fixed.
-        */
-        interface FreeTypeListener {
-            void typesInferred(InferenceContext inferenceContext);
-        }
+     class InferenceContext {
 
         /** list of inference vars as undet vars */
         List<Type> undetvars;
@@ -628,15 +1291,26 @@
         /** list of inference vars in this context */
         List<Type> inferencevars;
 
+        /** backed up inference variables */
+        List<Type> saved_undet;
+
         java.util.Map<FreeTypeListener, List<Type>> freeTypeListeners =
                 new java.util.HashMap<FreeTypeListener, List<Type>>();
 
         List<FreeTypeListener> freetypeListeners = List.nil();
 
-        public InferenceContext(List<Type> inferencevars, Infer infer, boolean includeBounds) {
-            this.undetvars = Type.map(inferencevars, infer.new FromTypeVarFun(includeBounds));
+        public InferenceContext(List<Type> inferencevars) {
+            this.undetvars = Type.map(inferencevars, fromTypeVarFun);
             this.inferencevars = inferencevars;
         }
+        //where
+            Mapping fromTypeVarFun = new Mapping("fromTypeVarFunWithBounds") {
+                // mapping that turns inference variables into undet vars
+                public Type apply(Type t) {
+                    if (t.hasTag(TYPEVAR)) return new UndetVar((TypeVar)t, types);
+                    else return t.map(this);
+                }
+            };
 
         /**
          * returns the list of free variables (as type-variables) in this
@@ -648,19 +1322,51 @@
 
         /**
          * returns the list of uninstantiated variables (as type-variables) in this
-         * inference context (usually called after instantiate())
+         * inference context
          */
         List<Type> restvars() {
-            List<Type> undetvars = this.undetvars;
-            ListBuffer<Type> restvars = ListBuffer.lb();
-            for (Type t : instTypes()) {
-                UndetVar uv = (UndetVar)undetvars.head;
-                if (uv.qtype == t) {
-                    restvars.append(t);
+            return filterVars(new Filter<UndetVar>() {
+                public boolean accepts(UndetVar uv) {
+                    return uv.inst == null;
                 }
-                undetvars = undetvars.tail;
+            });
+        }
+
+        /**
+         * returns the list of instantiated variables (as type-variables) in this
+         * inference context
+         */
+        List<Type> instvars() {
+            return filterVars(new Filter<UndetVar>() {
+                public boolean accepts(UndetVar uv) {
+                    return uv.inst != null;
+                }
+            });
+        }
+
+        /**
+         * Get list of bounded inference variables (where bound is other than
+         * declared bounds).
+         */
+        final List<Type> boundedVars() {
+            return filterVars(new Filter<UndetVar>() {
+                public boolean accepts(UndetVar uv) {
+                    return uv.getBounds(InferenceBound.UPPER)
+                            .diff(uv.getDeclaredBounds())
+                            .appendList(uv.getBounds(InferenceBound.EQ, InferenceBound.LOWER)).nonEmpty();
+                }
+            });
+        }
+
+        private List<Type> filterVars(Filter<UndetVar> fu) {
+            ListBuffer<Type> res = ListBuffer.lb();
+            for (Type t : undetvars) {
+                UndetVar uv = (UndetVar)t;
+                if (fu.accepts(uv)) {
+                    res.append(uv.qtype);
+                }
             }
-            return restvars.toList();
+            return res.toList();
         }
 
         /**
@@ -709,14 +1415,14 @@
          * undet vars (used ahead of subtyping/compatibility checks to allow propagation
          * of inference constraints).
          */
-        final Type asFree(Type t, Types types) {
+        final Type asFree(Type t) {
             return types.subst(t, inferencevars, undetvars);
         }
 
-        final List<Type> asFree(List<Type> ts, Types types) {
+        final List<Type> asFree(List<Type> ts) {
             ListBuffer<Type> buf = ListBuffer.lb();
             for (Type t : ts) {
-                buf.append(asFree(t, types));
+                buf.append(asFree(t));
             }
             return buf.toList();
         }
@@ -735,14 +1441,14 @@
          * instantiated types - if one or more free variable has not been
          * fully instantiated, it will still be available in the resulting type.
          */
-        Type asInstType(Type t, Types types) {
+        Type asInstType(Type t) {
             return types.subst(t, inferencevars, instTypes());
         }
 
-        List<Type> asInstTypes(List<Type> ts, Types types) {
+        List<Type> asInstTypes(List<Type> ts) {
             ListBuffer<Type> buf = ListBuffer.lb();
             for (Type t : ts) {
-                buf.append(asInstType(t, types));
+                buf.append(asInstType(t));
             }
             return buf.toList();
         }
@@ -758,11 +1464,15 @@
          * Mark the inference context as complete and trigger evaluation
          * of all deferred checks.
          */
-        void notifyChange(Types types) {
+        void notifyChange() {
+            notifyChange(inferencevars.diff(restvars()));
+        }
+
+        void notifyChange(List<Type> inferredVars) {
             InferenceException thrownEx = null;
             for (Map.Entry<FreeTypeListener, List<Type>> entry :
                     new HashMap<FreeTypeListener, List<Type>>(freeTypeListeners).entrySet()) {
-                if (!Type.containsAny(entry.getValue(), restvars())) {
+                if (!Type.containsAny(entry.getValue(), inferencevars.diff(inferredVars))) {
                     try {
                         entry.getKey().typesInferred(this);
                         freeTypeListeners.remove(entry.getKey());
@@ -780,22 +1490,156 @@
             }
         }
 
-        void solveAny(List<Type> varsToSolve, Types types, Infer infer) {
-            boolean progress = false;
-            for (Type t : varsToSolve) {
-                UndetVar uv = (UndetVar)asFree(t, types);
-                if (uv.inst == null) {
-                    infer.minimizeInst(uv, types.noWarnings);
-                    if (uv.inst != null) {
-                        progress = true;
+        /**
+         * Save the state of this inference context
+         */
+        void save() {
+            ListBuffer<Type> buf = ListBuffer.lb();
+            for (Type t : undetvars) {
+                UndetVar uv = (UndetVar)t;
+                UndetVar uv2 = new UndetVar((TypeVar)uv.qtype, types);
+                for (InferenceBound ib : InferenceBound.values()) {
+                    for (Type b : uv.getBounds(ib)) {
+                        uv2.addBound(ib, b, types);
+                    }
+                }
+                uv2.inst = uv.inst;
+                buf.add(uv2);
+            }
+            saved_undet = buf.toList();
+        }
+
+        /**
+         * Restore the state of this inference context to the previous known checkpoint
+         */
+        void rollback() {
+            Assert.check(saved_undet != null && saved_undet.length() == undetvars.length());
+            undetvars = saved_undet;
+            saved_undet = null;
+        }
+
+        /**
+         * Copy variable in this inference context to the given context
+         */
+        void dupTo(final InferenceContext that) {
+            that.inferencevars = that.inferencevars.appendList(inferencevars);
+            that.undetvars = that.undetvars.appendList(undetvars);
+            //set up listeners to notify original inference contexts as
+            //propagated vars are inferred in new context
+            for (Type t : inferencevars) {
+                that.freeTypeListeners.put(new FreeTypeListener() {
+                    public void typesInferred(InferenceContext inferenceContext) {
+                        InferenceContext.this.notifyChange();
+                    }
+                }, List.of(t));
+            }
+        }
+
+        /**
+         * Solve with given graph strategy.
+         */
+        private void solve(GraphStrategy ss, Warner warn) {
+            GraphSolver s = new GraphSolver(this, warn);
+            s.solve(ss);
+        }
+
+        /**
+         * Solve all variables in this context.
+         */
+        public void solve(Warner warn) {
+            solve(new LeafSolver() {
+                public boolean done() {
+                    return restvars().isEmpty();
+                }
+            }, warn);
+        }
+
+        /**
+         * Solve all variables in the given list.
+         */
+        public void solve(final List<Type> vars, Warner warn) {
+            solve(new BestLeafSolver(vars) {
+                public boolean done() {
+                    return !free(asInstTypes(vars));
+                }
+            }, warn);
+        }
+
+        /**
+         * Solve at least one variable in given list.
+         */
+        public void solveAny(List<Type> varsToSolve, Warner warn) {
+            checkWithinBounds(this, warn); //propagate bounds
+            List<Type> boundedVars = boundedVars().intersect(restvars()).intersect(varsToSolve);
+            if (boundedVars.isEmpty()) {
+                throw inferenceException.setMessage("cyclic.inference",
+                                freeVarsIn(varsToSolve));
+            }
+            solve(new BestLeafSolver(boundedVars) {
+                public boolean done() {
+                    return instvars().intersect(varsToSolve).nonEmpty();
+                }
+            }, warn);
+        }
+
+        /**
+         * Apply a set of inference steps
+         */
+        private boolean solveBasic(EnumSet<InferenceStep> steps) {
+            return solveBasic(inferencevars, steps);
+        }
+
+        private boolean solveBasic(List<Type> varsToSolve, EnumSet<InferenceStep> steps) {
+            boolean changed = false;
+            for (Type t : varsToSolve.intersect(restvars())) {
+                UndetVar uv = (UndetVar)asFree(t);
+                for (InferenceStep step : steps) {
+                    if (step.accepts(uv, this)) {
+                        uv.inst = step.solve(uv, this);
+                        changed = true;
+                        break;
                     }
                 }
             }
-            if (!progress) {
-                throw infer.inferenceException.setMessage("cyclic.inference", varsToSolve);
+            return changed;
+        }
+
+        /**
+         * Instantiate inference variables in legacy mode (JLS 15.12.2.7, 15.12.2.8).
+         * During overload resolution, instantiation is done by doing a partial
+         * inference process using eq/lower bound instantiation. During check,
+         * we also instantiate any remaining vars by repeatedly using eq/upper
+         * instantiation, until all variables are solved.
+         */
+        public void solveLegacy(boolean partial, Warner warn, EnumSet<InferenceStep> steps) {
+            while (true) {
+                boolean stuck = !solveBasic(steps);
+                if (restvars().isEmpty() || partial) {
+                    //all variables have been instantiated - exit
+                    break;
+                } else if (stuck) {
+                    //some variables could not be instantiated because of cycles in
+                    //upper bounds - provide a (possibly recursive) default instantiation
+                    instantiateAsUninferredVars(restvars(), this);
+                    break;
+                } else {
+                    //some variables have been instantiated - replace newly instantiated
+                    //variables in remaining upper bounds and continue
+                    for (Type t : undetvars) {
+                        UndetVar uv = (UndetVar)t;
+                        uv.substBounds(inferenceVars(), instTypes(), types);
+                    }
+                }
             }
+            checkWithinBounds(this, warn);
+        }
+
+        private Infer infer() {
+            //back-door to infer
+            return Infer.this;
         }
     }
 
-    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil(), this, false);
+    final InferenceContext emptyContext = new InferenceContext(List.<Type>nil());
+    // </editor-fold>
 }
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Sun Feb 17 16:44:55 2013 -0500
@@ -570,10 +570,19 @@
      *  @param flags    The class symbol's flags
      *  @param owner    The class symbol's owner
      */
-    ClassSymbol makeEmptyClass(long flags, ClassSymbol owner) {
+    JCClassDecl makeEmptyClass(long flags, ClassSymbol owner) {
+        return makeEmptyClass(flags, owner, null, true);
+    }
+
+    JCClassDecl makeEmptyClass(long flags, ClassSymbol owner, Name flatname,
+            boolean addToDefs) {
         // Create class symbol.
         ClassSymbol c = reader.defineClass(names.empty, owner);
-        c.flatname = chk.localClassName(c);
+        if (flatname != null) {
+            c.flatname = flatname;
+        } else {
+            c.flatname = chk.localClassName(c);
+        }
         c.sourcefile = owner.sourcefile;
         c.completer = null;
         c.members_field = new Scope(c);
@@ -597,9 +606,8 @@
         cdef.type = c.type;
 
         // Append class definition tree to owner's definitions.
-        odef.defs = odef.defs.prepend(cdef);
-
-        return c;
+        if (addToDefs) odef.defs = odef.defs.prepend(cdef);
+        return cdef;
     }
 
 /**************************************************************************
@@ -706,7 +714,7 @@
      * and synthethise a class (with makeEmptyClass) if one is not available.
      * However, there is a small possibility that an existing class will not
      * be generated as expected if it is inside a conditional with a constant
-     * expression. If that is found to be the case, create an empty class here.
+     * expression. If that is found to be the case, create an empty class tree here.
      */
     private void checkAccessConstructorTags() {
         for (List<ClassSymbol> l = accessConstrTags; l.nonEmpty(); l = l.tail) {
@@ -714,14 +722,10 @@
             if (isTranslatedClassAvailable(c))
                 continue;
             // Create class definition tree.
-            JCClassDecl cdef = make.ClassDef(
-                make.Modifiers(STATIC | SYNTHETIC), names.empty,
-                List.<JCTypeParameter>nil(),
-                null, List.<JCExpression>nil(), List.<JCTree>nil());
-            cdef.sym = c;
-            cdef.type = c.type;
-            // add it to the list of classes to be generated
-            translated.append(cdef);
+            JCClassDecl cdec = makeEmptyClass(STATIC | SYNTHETIC,
+                    c.outermostClass(), c.flatname, false);
+            swapAccessConstructorTag(c, cdec.sym);
+            translated.append(cdec);
         }
     }
     // where
@@ -735,6 +739,19 @@
         return false;
     }
 
+    void swapAccessConstructorTag(ClassSymbol oldCTag, ClassSymbol newCTag) {
+        for (MethodSymbol methodSymbol : accessConstrs.values()) {
+            Assert.check(methodSymbol.type.hasTag(METHOD));
+            MethodType oldMethodType =
+                    (MethodType)methodSymbol.type;
+            if (oldMethodType.argtypes.head.tsym == oldCTag)
+                methodSymbol.type =
+                    types.createMethodTypeWithParameters(oldMethodType,
+                        oldMethodType.getParameterTypes().tail
+                            .prepend(newCTag.erasure(types)));
+        }
+    }
+
 /**************************************************************************
  * Access methods
  *************************************************************************/
@@ -1211,7 +1228,7 @@
                                          "1");
         ClassSymbol ctag = chk.compiled.get(flatname);
         if (ctag == null)
-            ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass);
+            ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
         // keep a record of all tags, to verify that all are generated as required
         accessConstrTags = accessConstrTags.prepend(ctag);
         return ctag;
@@ -1428,22 +1445,49 @@
         return result;
     }
 
+    private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) {
+        if (owner.kind == TYP &&
+            target.usePrivateSyntheticFields())
+            flags |= PRIVATE;
+        Type target = types.erasure(owner.enclClass().type.getEnclosingType());
+        VarSymbol outerThis =
+            new VarSymbol(flags, outerThisName(target, owner), target, owner);
+        outerThisStack = outerThisStack.prepend(outerThis);
+        return outerThis;
+    }
+
+    private JCVariableDecl makeOuterThisVarDecl(int pos, VarSymbol sym) {
+        JCVariableDecl vd = make.at(pos).VarDef(sym, null);
+        vd.vartype = access(vd.vartype);
+        return vd;
+    }
+
+    /** Definition for this$n field.
+     *  @param pos        The source code position of the definition.
+     *  @param owner      The method in which the definition goes.
+     */
+    JCVariableDecl outerThisDef(int pos, MethodSymbol owner) {
+        ClassSymbol c = owner.enclClass();
+        boolean isMandated =
+            // Anonymous constructors
+            (owner.isConstructor() && owner.isAnonymous()) ||
+            // Constructors of non-private inner member classes
+            (owner.isConstructor() && c.isInner() &&
+             !c.isPrivate() && !c.isStatic());
+        long flags =
+            FINAL | (isMandated ? MANDATED : SYNTHETIC);
+        VarSymbol outerThis = makeOuterThisVarSymbol(owner, flags);
+        owner.extraParams = owner.extraParams.prepend(outerThis);
+        return makeOuterThisVarDecl(pos, outerThis);
+    }
+
     /** Definition for this$n field.
      *  @param pos        The source code position of the definition.
      *  @param owner      The class in which the definition goes.
      */
-    JCVariableDecl outerThisDef(int pos, Symbol owner) {
-        long flags = FINAL | SYNTHETIC;
-        if (owner.kind == TYP &&
-            target.usePrivateSyntheticFields())
-            flags |= PRIVATE;
-        Type target = types.erasure(owner.enclClass().type.getEnclosingType());
-        VarSymbol outerThis = new VarSymbol(
-            flags, outerThisName(target, owner), target, owner);
-        outerThisStack = outerThisStack.prepend(outerThis);
-        JCVariableDecl vd = make.at(pos).VarDef(outerThis, null);
-        vd.vartype = access(vd.vartype);
-        return vd;
+    JCVariableDecl outerThisDef(int pos, ClassSymbol owner) {
+        VarSymbol outerThis = makeOuterThisVarSymbol(owner, FINAL | SYNTHETIC);
+        return makeOuterThisVarDecl(pos, outerThis);
     }
 
     /** Return a list of trees that load the free variables in given list,
@@ -1778,7 +1822,7 @@
             if (e.sym.kind == TYP &&
                 e.sym.name == names.empty &&
                 (e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym;
-        return makeEmptyClass(STATIC | SYNTHETIC, clazz);
+        return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
     }
 
     /** Return symbol for "class$" method. If there is no method definition
@@ -2551,7 +2595,6 @@
                                        "enum" + target.syntheticNameChar() + "name"),
                       syms.stringType, tree.sym);
             nameParam.mods.flags |= SYNTHETIC; nameParam.sym.flags_field |= SYNTHETIC;
-
             JCVariableDecl ordParam = make.
                 Param(names.fromString(target.syntheticNameChar() +
                                        "enum" + target.syntheticNameChar() +
@@ -2562,6 +2605,8 @@
             tree.params = tree.params.prepend(ordParam).prepend(nameParam);
 
             MethodSymbol m = tree.sym;
+            m.extraParams = m.extraParams.prepend(ordParam.sym);
+            m.extraParams = m.extraParams.prepend(nameParam.sym);
             Type olderasure = m.erasure(types);
             m.erasure_field = new MethodType(
                 olderasure.getParameterTypes().prepend(syms.intType).prepend(syms.stringType),
@@ -3049,55 +3094,38 @@
     }
 
     public void visitAssignop(final JCAssignOp tree) {
-        if (!tree.lhs.type.isPrimitive() &&
-            tree.operator.type.getReturnType().isPrimitive()) {
-            // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
-            // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
-            // (but without recomputing x)
-            JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
-                    public JCTree build(final JCTree lhs) {
-                        JCTree.Tag newTag = tree.getTag().noAssignOp();
-                        // Erasure (TransTypes) can change the type of
-                        // tree.lhs.  However, we can still get the
-                        // unerased type of tree.lhs as it is stored
-                        // in tree.type in Attr.
-                        Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
-                                                                      newTag,
-                                                                      attrEnv,
-                                                                      tree.type,
-                                                                      tree.rhs.type);
-                        JCExpression expr = (JCExpression)lhs;
-                        if (expr.type != tree.type)
-                            expr = make.TypeCast(tree.type, expr);
-                        JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
-                        opResult.operator = newOperator;
-                        opResult.type = newOperator.type.getReturnType();
-                        JCTypeCast newRhs = make.TypeCast(types.unboxedType(tree.type),
-                                                          opResult);
-                        return make.Assign((JCExpression)lhs, newRhs).setType(tree.type);
-                    }
-                });
-            result = translate(newTree);
-            return;
-        }
-        tree.lhs = translate(tree.lhs, tree);
-        tree.rhs = translate(tree.rhs, tree.operator.type.getParameterTypes().tail.head);
-
-        // If translated left hand side is an Apply, we are
-        // seeing an access method invocation. In this case, append
-        // right hand side as last argument of the access method.
-        if (tree.lhs.hasTag(APPLY)) {
-            JCMethodInvocation app = (JCMethodInvocation)tree.lhs;
-            // if operation is a += on strings,
-            // make sure to convert argument to string
-            JCExpression rhs = (((OperatorSymbol)tree.operator).opcode == string_add)
-              ? makeString(tree.rhs)
-              : tree.rhs;
-            app.args = List.of(rhs).prependList(app.args);
-            result = app;
-        } else {
-            result = tree;
-        }
+        final boolean boxingReq = !tree.lhs.type.isPrimitive() &&
+            tree.operator.type.getReturnType().isPrimitive();
+
+        // boxing required; need to rewrite as x = (unbox typeof x)(x op y);
+        // or if x == (typeof x)z then z = (unbox typeof x)((typeof x)z op y)
+        // (but without recomputing x)
+        JCTree newTree = abstractLval(tree.lhs, new TreeBuilder() {
+                public JCTree build(final JCTree lhs) {
+                    JCTree.Tag newTag = tree.getTag().noAssignOp();
+                    // Erasure (TransTypes) can change the type of
+                    // tree.lhs.  However, we can still get the
+                    // unerased type of tree.lhs as it is stored
+                    // in tree.type in Attr.
+                    Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
+                                                                  newTag,
+                                                                  attrEnv,
+                                                                  tree.type,
+                                                                  tree.rhs.type);
+                    JCExpression expr = (JCExpression)lhs;
+                    if (expr.type != tree.type)
+                        expr = make.TypeCast(tree.type, expr);
+                    JCBinary opResult = make.Binary(newTag, expr, tree.rhs);
+                    opResult.operator = newOperator;
+                    opResult.type = newOperator.type.getReturnType();
+                    JCExpression newRhs = boxingReq ?
+                            make.TypeCast(types.unboxedType(tree.type),
+                                                      opResult) :
+                            opResult;
+                    return make.Assign((JCExpression)lhs, newRhs).setType(tree.type);
+                }
+            });
+        result = translate(newTree);
     }
 
     /** Lower a tree of the form e++ or e-- where e is an object type */
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Sun Feb 17 16:44:55 2013 -0500
@@ -465,7 +465,8 @@
                       names.valueOf,
                       make.Type(tree.sym.type),
                       List.<JCTypeParameter>nil(),
-                      List.of(make.VarDef(make.Modifiers(Flags.PARAMETER),
+                      List.of(make.VarDef(make.Modifiers(Flags.PARAMETER |
+                                                         Flags.MANDATED),
                                             names.fromString("name"),
                                             make.Type(syms.stringType), null)),
                       List.<JCExpression>nil(), // thrown
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Sun Feb 17 16:44:55 2013 -0500
@@ -35,7 +35,7 @@
 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
 import com.sun.tools.javac.comp.Infer.InferenceContext;
-import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
+import com.sun.tools.javac.comp.Infer.FreeTypeListener;
 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.tree.*;
@@ -564,7 +564,7 @@
                                     methodCheck,
                                     warn);
 
-        methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext),
+        methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
                                 argtypes, mt.getParameterTypes(), warn);
         return mt;
     }
@@ -741,7 +741,7 @@
                 inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
                     @Override
                     public void typesInferred(InferenceContext inferenceContext) {
-                        varargsAccessible(env, inferenceContext.asInstType(t, types), inferenceContext);
+                        varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext);
                     }
                 });
             } else {
@@ -785,8 +785,8 @@
 
         public boolean compatible(Type found, Type req, Warner warn) {
             return strict ?
-                    types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req, types), warn) :
-                    types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req, types), warn);
+                    types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req), warn) :
+                    types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req), warn);
         }
 
         public void report(DiagnosticPosition pos, JCDiagnostic details) {
@@ -3589,8 +3589,8 @@
             candidates = candidates.append(c);
         }
 
-        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext) {
-            return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext);
+        DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
+            return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn);
         }
 
         /**
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1490,12 +1490,13 @@
         position.type = type;
 
         switch (type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             position.offset = nextChar();
             break;
         // local variable
@@ -1544,9 +1545,12 @@
         case METHOD_FORMAL_PARAMETER:
             position.parameter_index = nextByte();
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             position.offset = nextChar();
             position.type_index = nextByte();
@@ -1555,10 +1559,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            position.parameter_index = nextByte();
-            break;
         case UNKNOWN:
             throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
         default:
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Sun Feb 17 16:44:55 2013 -0500
@@ -482,10 +482,8 @@
         while (i < pool.pp) {
             Object value = pool.pool[i];
             Assert.checkNonNull(value);
-            if (value instanceof Method)
-                value = ((Method)value).m;
-            else if (value instanceof Variable)
-                value = ((Variable)value).v;
+            if (value instanceof Method || value instanceof Variable)
+                value = ((DelegatedSymbol)value).getUnderlyingSymbol();
 
             if (value instanceof MethodSymbol) {
                 MethodSymbol m = (MethodSymbol)value;
@@ -730,14 +728,24 @@
      * Write method parameter names attribute.
      */
     int writeMethodParametersAttr(MethodSymbol m) {
-        if (m.params != null && 0 != m.params.length()) {
-            int attrIndex = writeAttr(names.MethodParameters);
-            databuf.appendByte(m.params.length());
+        MethodType ty = m.externalType(types).asMethodType();
+        final int allparams = ty.argtypes.size();
+        if (m.params != null && allparams != 0) {
+            final int attrIndex = writeAttr(names.MethodParameters);
+            databuf.appendByte(allparams);
+            // Write extra parameters first
+            for (VarSymbol s : m.extraParams) {
+                final int flags =
+                    ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) |
+                    ((int) m.flags() & SYNTHETIC);
+                databuf.appendChar(pool.put(s.name));
+                databuf.appendInt(flags);
+            }
+            // Now write the real parameters
             for (VarSymbol s : m.params) {
-                // TODO: expand to cover synthesized, once we figure out
-                // how to represent that.
-                final int flags = (int) s.flags() & (FINAL | SYNTHETIC);
-                // output parameter info
+                final int flags =
+                    ((int) s.flags() & (FINAL | SYNTHETIC | MANDATED)) |
+                    ((int) m.flags() & SYNTHETIC);
                 databuf.appendChar(pool.put(s.name));
                 databuf.appendInt(flags);
             }
@@ -994,12 +1002,13 @@
     void writePosition(TypeAnnotationPosition p) {
         databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte
         switch (p.type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             databuf.appendChar(p.offset);
             break;
         // local variable
@@ -1044,9 +1053,12 @@
         case METHOD_FORMAL_PARAMETER:
             databuf.appendByte(p.parameter_index);
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             databuf.appendChar(p.offset);
             databuf.appendByte(p.type_index);
@@ -1055,10 +1067,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            databuf.appendByte(p.parameter_index);
-            break;
         case UNKNOWN:
             throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!");
         default:
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Sun Feb 17 16:44:55 2013 -0500
@@ -513,7 +513,8 @@
         // that contains them as its body.
         if (clinitCode.length() != 0) {
             MethodSymbol clinit = new MethodSymbol(
-                STATIC, names.clinit,
+                STATIC | (c.flags() & STRICTFP),
+                names.clinit,
                 new MethodType(
                     List.<Type>nil(), syms.voidType,
                     List.<Type>nil(), syms.methodClass),
--- a/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/jvm/Pool.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,23 +140,23 @@
         return n == null ? -1 : n.intValue();
     }
 
-    static class Method extends DelegatedSymbol {
-        MethodSymbol m;
+    static class Method extends DelegatedSymbol<MethodSymbol> {
         UniqueType uniqueType;
         Method(MethodSymbol m, Types types) {
             super(m);
-            this.m = m;
             this.uniqueType = new UniqueType(m.type, types);
         }
-        public boolean equals(Object other) {
-            if (!(other instanceof Method)) return false;
-            MethodSymbol o = ((Method)other).m;
+        public boolean equals(Object any) {
+            if (!(any instanceof Method)) return false;
+            MethodSymbol o = ((Method)any).other;
+            MethodSymbol m = this.other;
             return
                 o.name == m.name &&
                 o.owner == m.owner &&
-                ((Method)other).uniqueType.equals(uniqueType);
+                ((Method)any).uniqueType.equals(uniqueType);
         }
         public int hashCode() {
+            MethodSymbol m = this.other;
             return
                 m.name.hashCode() * 33 +
                 m.owner.hashCode() * 9 +
@@ -173,21 +173,21 @@
         }
 
         @Override
-        public boolean equals(Object other) {
-            if (!super.equals(other)) return false;
-            if (!(other instanceof DynamicMethod)) return false;
-            DynamicMethodSymbol dm1 = (DynamicMethodSymbol)m;
-            DynamicMethodSymbol dm2 = (DynamicMethodSymbol)((DynamicMethod)other).m;
+        public boolean equals(Object any) {
+            if (!super.equals(any)) return false;
+            if (!(any instanceof DynamicMethod)) return false;
+            DynamicMethodSymbol dm1 = (DynamicMethodSymbol)other;
+            DynamicMethodSymbol dm2 = (DynamicMethodSymbol)((DynamicMethod)any).other;
             return dm1.bsm == dm2.bsm &&
                         dm1.bsmKind == dm2.bsmKind &&
                         Arrays.equals(uniqueStaticArgs,
-                            ((DynamicMethod)other).uniqueStaticArgs);
+                            ((DynamicMethod)any).uniqueStaticArgs);
         }
 
         @Override
         public int hashCode() {
             int hash = super.hashCode();
-            DynamicMethodSymbol dm = (DynamicMethodSymbol)m;
+            DynamicMethodSymbol dm = (DynamicMethodSymbol)other;
             hash += dm.bsmKind * 7 +
                     dm.bsm.hashCode() * 11;
             for (int i = 0; i < dm.staticArgs.length; i++) {
@@ -209,23 +209,23 @@
         }
     }
 
-    static class Variable extends DelegatedSymbol {
-        VarSymbol v;
+    static class Variable extends DelegatedSymbol<VarSymbol> {
         UniqueType uniqueType;
         Variable(VarSymbol v, Types types) {
             super(v);
-            this.v = v;
             this.uniqueType = new UniqueType(v.type, types);
         }
-        public boolean equals(Object other) {
-            if (!(other instanceof Variable)) return false;
-            VarSymbol o = ((Variable)other).v;
+        public boolean equals(Object any) {
+            if (!(any instanceof Variable)) return false;
+            VarSymbol o = ((Variable)any).other;
+            VarSymbol v = other;
             return
                 o.name == v.name &&
                 o.owner == v.owner &&
-                ((Variable)other).uniqueType.equals(uniqueType);
+                ((Variable)any).uniqueType.equals(uniqueType);
         }
         public int hashCode() {
+            VarSymbol v = other;
             return
                 v.name.hashCode() * 33 +
                 v.owner.hashCode() * 9 +
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Sun Feb 17 16:44:55 2013 -0500
@@ -629,6 +629,8 @@
             if (!taskListener.isEmpty()) {
                 TaskEvent e = new TaskEvent(TaskEvent.Kind.PARSE, filename);
                 taskListener.started(e);
+                keepComments = true;
+                genEndPos = true;
             }
             Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo);
             tree = parser.parseCompilationUnit();
--- a/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Sun Feb 17 16:44:55 2013 -0500
@@ -760,6 +760,16 @@
         return names.fromString(cs.toString());
     }
 
+    @Override
+    public boolean isFunctionalInterface(TypeElement element) {
+        if (element.getKind() != ElementKind.INTERFACE)
+            return false;
+        else {
+            TypeSymbol tsym = cast(TypeSymbol.class, element);
+            return types.isFunctionalInterface(tsym);
+        }
+    }
+
     /**
      * Returns the tree node and compilation unit corresponding to this
      * element, or null if they can't be found.
--- a/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/parser/DocCommentParser.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -279,13 +279,7 @@
         try {
             nextChar();
             if (isIdentifierStart(ch)) {
-                int namePos = bp;
-                nextChar();
-                while (isIdentifierPart(ch))
-                    nextChar();
-                int nameLen = bp - namePos;
-
-                Name name = names.fromChars(buf, namePos, nameLen);
+                Name name = readIdentifier();
                 TagParser tp = tagParsers.get(name);
                 if (tp == null) {
                     List<DCTree> content = blockContent();
@@ -334,14 +328,9 @@
         try {
             nextChar();
             if (isIdentifierStart(ch)) {
-                int namePos = bp;
-                nextChar();
-                while (isIdentifierPart(ch))
-                    nextChar();
-                int nameLen = bp - namePos;
+                Name name = readIdentifier();
                 skipWhitespace();
 
-                Name name = names.fromChars(buf, namePos, nameLen);
                 TagParser tp = tagParsers.get(name);
                 if (tp == null) {
                     DCTree text = inlineText();
@@ -575,10 +564,8 @@
         int pos = bp;
 
         if (isJavaIdentifierStart(ch)) {
-            nextChar();
-            while (isJavaIdentifierPart(ch))
-                nextChar();
-            return m.at(pos).Identifier(names.fromChars(buf, pos, bp - pos));
+            Name name = readJavaIdentifier();
+            return m.at(pos).Identifier(name);
         }
 
         throw new ParseException("dc.identifier.expected");
@@ -703,39 +690,36 @@
     protected DCTree entity() {
         int p = bp;
         nextChar();
-        int namep = bp;
+        Name name = null;
         boolean checkSemi = false;
         if (ch == '#') {
+            int namep = bp;
             nextChar();
             if (isDecimalDigit(ch)) {
                 nextChar();
                 while (isDecimalDigit(ch))
                     nextChar();
-                checkSemi = true;
+                name = names.fromChars(buf, namep, bp - namep);
             } else if (ch == 'x' || ch == 'X') {
                 nextChar();
                 if (isHexDigit(ch)) {
                     nextChar();
                     while (isHexDigit(ch))
                         nextChar();
-                    checkSemi = true;
+                    name = names.fromChars(buf, namep, bp - namep);
                 }
             }
         } else if (isIdentifierStart(ch)) {
-            nextChar();
-            while (isIdentifierPart(ch))
-                nextChar();
-            checkSemi = true;
+            name = readIdentifier();
         }
 
-        if (checkSemi && ch == ';') {
+        if (name == null)
+            return erroneous("dc.bad.entity", p);
+        else {
+            if (ch != ';')
+                return erroneous("dc.missing.semicolon", p);
             nextChar();
-            return m.at(p).Entity(names.fromChars(buf, namep, bp - namep - 1));
-        } else {
-            String code = checkSemi
-                    ? "dc.missing.semicolon"
-                    : "dc.bad.entity";
-            return erroneous(code, p);
+            return m.at(p).Entity(name);
         }
     }
 
@@ -747,11 +731,7 @@
         int p = bp;
         nextChar();
         if (isIdentifierStart(ch)) {
-            int namePos = bp;
-            nextChar();
-            while (isIdentifierPart(ch))
-                nextChar();
-            int nameLen = bp - namePos;
+            Name name = readIdentifier();
             List<DCTree> attrs = htmlAttrs();
             if (attrs != null) {
                 boolean selfClosing = false;
@@ -761,22 +741,16 @@
                 }
                 if (ch == '>') {
                     nextChar();
-                    Name name = names.fromChars(buf, namePos, nameLen);
                     return m.at(p).StartElement(name, attrs, selfClosing);
                 }
             }
         } else if (ch == '/') {
             nextChar();
             if (isIdentifierStart(ch)) {
-                int namePos = bp;
-                nextChar();
-                while (isIdentifierPart(ch))
-                    nextChar();
-                int nameLen = bp - namePos;
+                Name name = readIdentifier();
                 skipWhitespace();
                 if (ch == '>') {
                     nextChar();
-                    Name name = names.fromChars(buf, namePos, nameLen);
                     return m.at(p).EndElement(name);
                 }
             }
@@ -822,10 +796,7 @@
         loop:
         while (isIdentifierStart(ch)) {
             int namePos = bp;
-            nextChar();
-            while (isIdentifierPart(ch))
-                nextChar();
-            int nameLen = bp - namePos;
+            Name name = readIdentifier();
             skipWhitespace();
             List<DCTree> value = null;
             ValueKind vkind = ValueKind.EMPTY;
@@ -862,7 +833,6 @@
                 skipWhitespace();
                 value = v.toList();
             }
-            Name name = names.fromChars(buf, namePos, nameLen);
             DCAttribute attr = m.at(namePos).Attribute(name, vkind, value);
             attrs.add(attr);
         }
@@ -897,7 +867,7 @@
     protected DCErroneous erroneous(String code, int pos) {
         int i = bp - 1;
         loop:
-        while (i > 0) {
+        while (i > pos) {
             switch (buf[i]) {
                 case '\f': case '\n': case '\r':
                     newline = true;
@@ -926,16 +896,24 @@
         return Character.isUnicodeIdentifierStart(ch);
     }
 
-    protected boolean isIdentifierPart(char ch) {
-        return Character.isUnicodeIdentifierPart(ch);
+    protected Name readIdentifier() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen && Character.isUnicodeIdentifierPart(ch))
+            nextChar();
+        return names.fromChars(buf, start, bp - start);
     }
 
     protected boolean isJavaIdentifierStart(char ch) {
         return Character.isJavaIdentifierStart(ch);
     }
 
-    protected boolean isJavaIdentifierPart(char ch) {
-        return Character.isJavaIdentifierPart(ch);
+    protected Name readJavaIdentifier() {
+        int start = bp;
+        nextChar();
+        while (bp < buflen && Character.isJavaIdentifierPart(ch))
+            nextChar();
+        return names.fromChars(buf, start, bp - start);
     }
 
     protected boolean isDecimalDigit(char ch) {
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1164,7 +1164,7 @@
             } else return illegal();
             break;
         case MONKEYS_AT:
-            // Only annotated cast types are valid
+            // Only annotated cast types and method references are valid
             List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
             if (typeAnnos.isEmpty()) {
                 // else there would be no '@'
@@ -1175,17 +1175,27 @@
 
             if ((mode & TYPE) == 0) {
                 // Type annotations on class literals no longer legal
-                if (!expr.hasTag(Tag.SELECT)) {
+                switch (expr.getTag()) {
+                case REFERENCE: {
+                    JCMemberReference mref = (JCMemberReference) expr;
+                    mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr));
+                    t = mref;
+                    break;
+                }
+                case SELECT: {
+                    JCFieldAccess sel = (JCFieldAccess) expr;
+
+                    if (sel.name != names._class) {
+                        return illegal();
+                    } else {
+                        log.error(token.pos, "no.annotations.on.dot.class");
+                        return expr;
+                    }
+                }
+                default:
                     return illegal(typeAnnos.head.pos);
                 }
-                JCFieldAccess sel = (JCFieldAccess)expr;
-
-                if (sel.name != names._class) {
-                    return illegal();
-                } else {
-                    log.error(token.pos, "no.annotations.on.dot.class");
-                    return expr;
-                }
+
             } else {
                 // Type annotations targeting a cast
                 t = insertAnnotationsToMostInner(expr, typeAnnos, false);
@@ -1457,18 +1467,40 @@
     /**
      * If we see an identifier followed by a '&lt;' it could be an unbound
      * method reference or a binary expression. To disambiguate, look for a
-     * matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
+     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
      */
     @SuppressWarnings("fallthrough")
     boolean isUnboundMemberRef() {
         int pos = 0, depth = 0;
-        for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
+        outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
             switch (t.kind) {
                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
                 case DOUBLE: case BOOLEAN: case CHAR:
+                case MONKEYS_AT:
                     break;
+
+                case LPAREN:
+                    // skip annotation values
+                    int nesting = 0;
+                    for (; ; pos++) {
+                        TokenKind tk2 = S.token(pos).kind;
+                        switch (tk2) {
+                            case EOF:
+                                return false;
+                            case LPAREN:
+                                nesting++;
+                                break;
+                            case RPAREN:
+                                nesting--;
+                                if (nesting == 0) {
+                                    continue outer;
+                                }
+                                break;
+                        }
+                    }
+
                 case LT:
                     depth++; break;
                 case GTGTGT:
@@ -1494,7 +1526,7 @@
     /**
      * If we see an identifier followed by a '&lt;' it could be an unbound
      * method reference or a binary expression. To disambiguate, look for a
-     * matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
+     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
      */
     @SuppressWarnings("fallthrough")
     ParensResult analyzeParens() {
@@ -3022,7 +3054,7 @@
         boolean checkForImports = true;
         boolean firstTypeDecl = true;
         while (token.kind != EOF) {
-            if (token.pos <= endPosTable.errorEndPos) {
+            if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
                 // error recovery
                 skip(checkForImports, false, false, false);
                 if (token.kind == EOF)
--- a/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -236,7 +236,7 @@
             // relative to the best match found in the array.
             if (pos == Position.NOPOS)
                 return Position.NOPOS;
-            if (pos < 0 || pos >= docComment.length())
+            if (pos < 0 || pos > docComment.length())
                 throw new StringIndexOutOfBoundsException(String.valueOf(pos));
             if (docPosns == null)
                 return Position.NOPOS;
--- a/src/share/classes/com/sun/tools/javac/tree/DCTree.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/tree/DCTree.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -119,7 +119,7 @@
 
     }
 
-    public static abstract class DCBlockTag extends DCTree implements InlineTagTree {
+    public static abstract class DCBlockTag extends DCTree implements BlockTagTree {
         public String getTagName() {
             return getKind().tagName;
         }
@@ -169,7 +169,7 @@
         }
     }
 
-    public static class DCAuthor extends DCInlineTag implements AuthorTree {
+    public static class DCAuthor extends DCBlockTag implements AuthorTree {
         public final List<DCTree> name;
 
         DCAuthor(List<DCTree> name) {
@@ -640,7 +640,7 @@
         }
     }
 
-    public static class DCSince extends DCInlineTag implements SinceTree {
+    public static class DCSince extends DCBlockTag implements SinceTree {
         public final List<DCTree> body;
 
         DCSince(List<DCTree> body) {
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Sun Feb 17 16:44:55 2013 -0500
@@ -235,6 +235,7 @@
         switch(tree.getTag()) {
             case TYPEAPPLY: return ((JCTypeApply)tree).getTypeArguments().isEmpty();
             case NEWCLASS: return isDiamond(((JCNewClass)tree).clazz);
+            case ANNOTATED_TYPE: return isDiamond(((JCAnnotatedType)tree).underlyingType);
             default: return false;
         }
     }
@@ -335,6 +336,8 @@
             case TYPEAPPLY:
             case TYPEARRAY:
                 return true;
+            case ANNOTATED_TYPE:
+                return isStaticSelector(((JCAnnotatedType)base).underlyingType, names);
             default:
                 return false;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/util/GraphUtils.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.util;
+
+/** <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class GraphUtils {
+
+    /**
+     * This class is a basic abstract class for representing a node.
+     * A node is associated with a given data.
+     */
+    public static abstract class Node<D> {
+        public final D data;
+
+        public Node(D data) {
+            this.data = data;
+        }
+
+        public abstract Iterable<? extends Node<D>> getDependencies();
+
+        public abstract String printDependency(Node<D> to);
+
+        @Override
+        public String toString() {
+            return data.toString();
+        }
+    }
+
+    /**
+     * This class specialized Node, by adding elements that are required in order
+     * to perform Tarjan computation of strongly connected components.
+     */
+    public static abstract class TarjanNode<D> extends Node<D> implements Comparable<TarjanNode<D>> {
+        int index = -1;
+        int lowlink;
+        boolean active;
+
+        public TarjanNode(D data) {
+            super(data);
+        }
+
+        public abstract Iterable<? extends TarjanNode<D>> getDependencies();
+
+        public int compareTo(TarjanNode<D> o) {
+            return (index < o.index) ? -1 : (index == o.index) ? 0 : 1;
+        }
+    }
+
+    /**
+     * Tarjan's algorithm to determine strongly connected components of a
+     * directed graph in linear time. Works on TarjanNode.
+     */
+    public static <D, N extends TarjanNode<D>> List<? extends List<? extends N>> tarjan(Iterable<? extends N> nodes) {
+        ListBuffer<List<N>> cycles = ListBuffer.lb();
+        ListBuffer<N> stack = ListBuffer.lb();
+        int index = 0;
+        for (N node: nodes) {
+            if (node.index == -1) {
+                index += tarjan(node, index, stack, cycles);
+            }
+        }
+        return cycles.toList();
+    }
+
+    private static <D, N extends TarjanNode<D>> int tarjan(N v, int index, ListBuffer<N> stack, ListBuffer<List<N>> cycles) {
+        v.index = index;
+        v.lowlink = index;
+        index++;
+        stack.prepend(v);
+        v.active = true;
+        for (TarjanNode<D> nd: v.getDependencies()) {
+            @SuppressWarnings("unchecked")
+            N n = (N)nd;
+            if (n.index == -1) {
+                tarjan(n, index, stack, cycles);
+                v.lowlink = Math.min(v.lowlink, n.lowlink);
+            } else if (stack.contains(n)) {
+                v.lowlink = Math.min(v.lowlink, n.index);
+            }
+        }
+        if (v.lowlink == v.index) {
+            N n;
+            ListBuffer<N> cycle = ListBuffer.lb();
+            do {
+                n = stack.remove();
+                n.active = false;
+                cycle.add(n);
+            } while (n != v);
+            cycles.add(cycle.toList());
+        }
+        return index;
+    }
+
+    /**
+     * Debugging: dot representation of a set of connected nodes. The resulting
+     * dot representation will use {@code Node.toString} to display node labels
+     * and {@code Node.printDependency} to display edge labels. The resulting
+     * representation is also customizable with a graph name and a header.
+     */
+    public static <D> String toDot(Iterable<? extends TarjanNode<D>> nodes, String name, String header) {
+        StringBuilder buf = new StringBuilder();
+        buf.append(String.format("digraph %s {\n", name));
+        buf.append(String.format("label = \"%s\";\n", header));
+        //dump nodes
+        for (TarjanNode<D> n : nodes) {
+            buf.append(String.format("%s [label = \"%s\"];\n", n.hashCode(), n.toString()));
+        }
+        //dump arcs
+        for (TarjanNode<D> from : nodes) {
+            for (TarjanNode<D> to : from.getDependencies()) {
+                buf.append(String.format("%s -> %s [label = \" %s \"];\n",
+                        from.hashCode(), to.hashCode(), from.printDependency(to)));
+            }
+        }
+        buf.append("}\n");
+        return buf.toString();
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/util/List.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javac/util/List.java	Sun Feb 17 16:44:55 2013 -0500
@@ -96,6 +96,26 @@
         return res.reverse();
     }
 
+    public List<A> intersect(List<A> that) {
+        ListBuffer<A> buf = ListBuffer.lb();
+        for (A el : this) {
+            if (that.contains(el)) {
+                buf.append(el);
+            }
+        }
+        return buf.toList();
+    }
+
+    public List<A> diff(List<A> that) {
+        ListBuffer<A> buf = ListBuffer.lb();
+        for (A el : this) {
+            if (!that.contains(el)) {
+                buf.append(el);
+            }
+        }
+        return buf.toList();
+    }
+
     /** Construct a list consisting of given element.
      */
     public static <A> List<A> of(A x1) {
--- a/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javadoc/DocEnv.java	Sun Feb 17 16:44:55 2013 -0500
@@ -801,7 +801,9 @@
             doclintOpts.add(opt == null ? DocLint.XMSGS_OPTION : DocLint.XMSGS_CUSTOM_PREFIX + opt);
         }
 
-        if (doclintOpts.size() == 1
+        if (doclintOpts.isEmpty()) {
+            doclintOpts.add(DocLint.XMSGS_OPTION);
+        } else if (doclintOpts.size() == 1
                 && doclintOpts.get(0).equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) {
             return;
         }
--- a/src/share/classes/com/sun/tools/javadoc/api/JavadocTool.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javadoc/api/JavadocTool.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -139,12 +139,13 @@
 
     @Override
     public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
-        PrintWriter err_pw = new PrintWriter(err, true);
-        PrintWriter out_pw = new PrintWriter(out);
+        PrintWriter err_pw = new PrintWriter(err == null ? System.err : err, true);
+        PrintWriter out_pw = new PrintWriter(out == null ? System.out : out);
         try {
             String standardDocletName = "com.sun.tools.doclets.standard.Standard";
+            ClassLoader cl = getClass().getClassLoader();
             return com.sun.tools.javadoc.Main.execute(
-                    "javadoc", err_pw, err_pw, out_pw, standardDocletName, arguments);
+                    "javadoc", err_pw, err_pw, out_pw, standardDocletName, cl, arguments);
         } finally {
             err_pw.flush();
             out_pw.flush();
--- a/src/share/classes/com/sun/tools/javap/AnnotationWriter.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javap/AnnotationWriter.java	Sun Feb 17 16:44:55 2013 -0500
@@ -91,12 +91,13 @@
         print(pos.type);
 
         switch (pos.type) {
-        // type cast
-        case CAST:
         // instanceof
         case INSTANCEOF:
         // new expression
         case NEW:
+        // constructor/method reference receiver
+        case CONSTRUCTOR_REFERENCE:
+        case METHOD_REFERENCE:
             if (showOffsets) {
                 print(", offset=");
                 print(pos.offset);
@@ -162,9 +163,12 @@
             print(", param_index=");
             print(pos.parameter_index);
             break;
+        // type cast
+        case CAST:
         // method/constructor/reference type argument
         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
         case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
         case METHOD_REFERENCE_TYPE_ARGUMENT:
             if (showOffsets) {
                 print(", offset=");
@@ -177,11 +181,6 @@
         case METHOD_RETURN:
         case FIELD:
             break;
-        // lambda formal parameter
-        case LAMBDA_FORMAL_PARAMETER:
-            print(", param_index=");
-            print(pos.parameter_index);
-            break;
         case UNKNOWN:
             throw new AssertionError("AnnotationWriter: UNKNOWN target type should never occur!");
         default:
--- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Sun Feb 17 16:44:55 2013 -0500
@@ -400,12 +400,14 @@
         println(header);
         for (MethodParameters_attribute.Entry entry :
                  attr.method_parameter_table) {
+            String namestr =
+                entry.name_index != 0 ?
+                constantWriter.stringValue(entry.name_index) : "<no name>";
             String flagstr =
-                (0 != (entry.flags & ACC_FINAL) ? " final" : "") +
-                (0 != (entry.flags & ACC_SYNTHETIC) ? " synthetic" : "");
-            println(String.format(format,
-                                  constantWriter.stringValue(entry.name_index),
-                                  flagstr));
+                (0 != (entry.flags & ACC_FINAL) ? "final " : "") +
+                (0 != (entry.flags & ACC_MANDATED) ? "mandated " : "") +
+                (0 != (entry.flags & ACC_SYNTHETIC) ? "synthetic" : "");
+            println(String.format(format, namestr, flagstr));
         }
         indent(-1);
         return null;
--- a/src/share/classes/com/sun/tools/javap/JavapTask.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/com/sun/tools/javap/JavapTask.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -362,7 +362,8 @@
         }
 
         try {
-            handleOptions(options, false);
+            if (options != null)
+                handleOptions(options, false);
         } catch (BadArgs e) {
             throw new IllegalArgumentException(e.getMessage());
         }
--- a/src/share/classes/javax/lang/model/element/Element.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/javax/lang/model/element/Element.java	Sun Feb 17 16:44:55 2013 -0500
@@ -149,12 +149,15 @@
     <A extends Annotation> A getAnnotation(Class<A> annotationType);
 
     /**
-     * Returns an array of all of this element's annotation for the
-     * specified type if such annotations are present, else an empty
-     * array.  The annotation may be either inherited or directly
-     * present on this element. This method will look through a container
-     * annotation (if present) if the supplied annotation type is
-     * repeatable.
+     * Returns annotations that are <em>present</em> on this element.
+     *
+     * If there are no annotations <em>present</em> on this element, the return
+     * value is an array of length 0.
+     *
+     * The difference between this method and {@link #getAnnotation(Class)}
+     * is that this method detects if its argument is a <em>repeatable
+     * annotation type</em> (JLS 9.6), and if so, attempts to find one or more
+     * annotations of that type by "looking through" a container annotation.
      *
      * <p> The annotations returned by this method could contain an element
      * whose value is of type {@code Class}.
@@ -189,14 +192,14 @@
      *
      * @see #getAnnotationMirrors()
      * @see #getAnnotation(java.lang.Class)
-     * @see java.lang.reflect.AnnotatedElement#getAnnotations
+     * @see java.lang.reflect.AnnotatedElement#getAnnotationsByType
      * @see EnumConstantNotPresentException
      * @see AnnotationTypeMismatchException
      * @see IncompleteAnnotationException
      * @see MirroredTypeException
      * @see MirroredTypesException
      */
-    <A extends Annotation> A[] getAnnotations(Class<A> annotationType);
+    <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType);
 
     /**
      * Returns the modifiers of this element, excluding annotations.
--- a/src/share/classes/javax/lang/model/element/TypeElement.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/javax/lang/model/element/TypeElement.java	Sun Feb 17 16:44:55 2013 -0500
@@ -111,7 +111,6 @@
      */
     Name getQualifiedName();
 
-
     /**
      * Returns the simple name of this type element.
      *
@@ -152,7 +151,6 @@
      */
     List<? extends TypeParameterElement> getTypeParameters();
 
-
     /**
      * Returns the package of a top-level type and returns the
      * immediately lexically enclosing element for a {@linkplain
--- a/src/share/classes/javax/lang/model/util/Elements.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/src/share/classes/javax/lang/model/util/Elements.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -249,4 +249,14 @@
      * @param cs the character sequence to return as a name
      */
     Name getName(CharSequence cs);
+
+    /**
+     * Returns {@code true} if the type element is a functional interface, {@code false} otherwise.
+     *
+     * @param type the type element being examined
+     * @return {@code true} if the element is a functional interface, {@code false} otherwise
+     * @jls 9.8 Functional Interfaces
+     * @since 1.8
+     */
+    boolean isFunctionalInterface(TypeElement type);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/jdk/Supported.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk;
+
+import java.lang.annotation.*;
+
+/**
+  * Indicates whether or not a JDK specific type or package is a
+  * supported part of the JDK.
+  *
+  * This annotation should only be applied to types and packages
+  * <em>outside</em> of the Java SE namespaces of {@code java.*} and
+  * {@code javax.*} packages.  For example, certain portions of {@code
+  * com.sun.*} are official parts of the JDK meant to be generally
+  * usable while other portions of {@code com.sun.*} are not.  This
+  * annotation type allows those portions to be easily and
+  * programmaticly distinguished.
+  *
+  * @since 1.8
+  */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.PACKAGE})
+@Supported
+public @interface Supported {
+    /**
+     * Whether or not this package or type is a supported part of the JDK.
+     */
+    boolean value() default true;
+}
--- a/test/com/sun/javadoc/T6735320/T6735320.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/com/sun/javadoc/T6735320/T6735320.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,8 +47,8 @@
 
     public static void main(String... args) {
         T6735320 tester = new T6735320();
-        if (tester.runJavadoc(ARGS) != 0) {
-            throw new AssertionError("non-zero return code from javadoc");
+        if (tester.runJavadoc(ARGS) == 0) {
+            throw new AssertionError("zero return code from javadoc");
         }
         if (tester.getErrorOutput().contains("StringIndexOutOfBoundsException")) {
             throw new AssertionError("javadoc threw StringIndexOutOfBoundsException");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/doclint/EndWithIdentifierTest.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,32 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8007096
+ * @summary DocLint parsing problems with some comments
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html EndWithIdentifierTest.java
+ * @run main DocLintTester -Xmsgs -ref EndWithIdentifierTest.out EndWithIdentifierTest.java
+ * @author jlahoda
+ */
+
+/**@deprecated*/
+public class EndWithIdentifierTest {
+
+    /**{@link*/
+    private void unfinishedInlineTagName() {}
+
+    /**@see List*/
+    private void endsWithIdentifier() {}
+
+    /**&amp*/
+    private void entityName() {}
+
+    /**<a*/
+    private void tag() {}
+
+    /**</a*/
+    private void tagEnd() {}
+
+    /**<a name*/
+    private void attribute() {}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/doclint/EndWithIdentifierTest.out	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,20 @@
+EndWithIdentifierTest.java:14: error: syntax error in reference
+    /**{@link*/
+       ^
+EndWithIdentifierTest.java:17: error: reference not found
+    /**@see List*/
+            ^
+EndWithIdentifierTest.java:20: error: semicolon missing
+    /**&amp*/
+       ^
+EndWithIdentifierTest.java:23: error: malformed HTML
+    /**<a*/
+       ^
+EndWithIdentifierTest.java:26: error: malformed HTML
+    /**</a*/
+       ^
+EndWithIdentifierTest.java:29: error: malformed HTML
+    /**<a name*/
+       ^
+6 errors
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/doclint/ParaTagTest.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007566
+ * @summary DocLint too aggressive with not allowed here: <p>
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs ParaTagTest.java
+ */
+
+/**
+ * First line.
+ * <p> Para c1.</p>
+ * <p> Para c2.
+ * <p> Para c3.</p>
+ */
+public class ParaTagTest {
+    /**
+     * m1 <code>code </code>.
+     * <p> Para m1.
+     * <p> Para m2.
+     */
+    public void m() {}
+
+    /**
+     * m2.
+     * <p> Para z1.
+     * <p> Para z2.
+     * <pre>
+     *    Preformat 1.
+     * </pre>
+     */
+    public void z() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/doclint/UnfinishedInlineTagTest.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8007096
+ * @summary DocLint parsing problems with some comments
+ * @build DocLintTester
+ * @run main DocLintTester -Xmsgs:-html UnfinishedInlineTagTest.java
+ * @run main DocLintTester -Xmsgs -ref UnfinishedInlineTagTest.out UnfinishedInlineTagTest.java
+ * @author jlahoda
+ */
+
+import java.util.List;
+
+/**{@link List
+ */
+public class UnfinishedInlineTagTest {
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/doclint/UnfinishedInlineTagTest.out	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,5 @@
+UnfinishedInlineTagTest.java:14: error: unterminated inline tag
+ */
+^
+1 error
+
--- a/test/tools/javac/6758789/T6758789b.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/6758789/T6758789b.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,4 +1,4 @@
-T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<X>
+T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo<java.lang.Object>
 T6758789b.java:16:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo<X>, T6758789a.Foo, kindname.class, T6758789a
 - compiler.err.warnings.and.werror
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7166455
+ * @summary javac doesn't set ACC_STRICT bit on <clinit> for strictfp class
+ * @run main CheckACC_STRICTFlagOnclinitTest
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+import java.io.IOException;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.Method;
+
+import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
+
+public strictfp class CheckACC_STRICTFlagOnclinitTest {
+    private static final String AssertionErrorMessage =
+        "All methods should have the ACC_STRICT access flag " +
+        "please check output";
+    private static final String offendingMethodErrorMessage =
+        "Method %s of class %s doesn't have the ACC_STRICT access flag";
+
+    static {
+        class Foo {
+            class Bar {
+                void m11() {}
+            }
+            void m1() {}
+        }
+    }
+    void m2() {
+        class Any {
+            void m21() {}
+        }
+    }
+
+    private List<String> errors = new ArrayList<>();
+
+    public static void main(String[] args)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        new CheckACC_STRICTFlagOnclinitTest().run();
+    }
+
+    private void run()
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        String testClasses = System.getProperty("test.classes");
+        check(testClasses,
+              "CheckACC_STRICTFlagOnclinitTest.class",
+              "CheckACC_STRICTFlagOnclinitTest$1Foo.class",
+              "CheckACC_STRICTFlagOnclinitTest$1Foo$Bar.class",
+              "CheckACC_STRICTFlagOnclinitTest$1Any.class");
+        if (errors.size() > 0) {
+            for (String error: errors) {
+                System.err.println(error);
+            }
+            throw new AssertionError(AssertionErrorMessage);
+        }
+    }
+
+    void check(String dir, String... fileNames)
+        throws
+            IOException,
+            ConstantPoolException,
+            Descriptor.InvalidDescriptor {
+        for (String fileName : fileNames) {
+            ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName));
+
+            for (Method method : classFileToCheck.methods) {
+                if ((method.access_flags.flags & ACC_STRICT) == 0) {
+                    errors.add(String.format(offendingMethodErrorMessage,
+                            method.getName(classFileToCheck.constant_pool),
+                            classFileToCheck.getName()));
+                }
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/7167125/DiffResultAfterSameOperationInnerClasses.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7167125
+ * @summary Two variables after the same operation in a inner class return
+ * different results
+ * @run main DiffResultAfterSameOperationInnerClasses
+ */
+
+public class DiffResultAfterSameOperationInnerClasses {
+    public int i = 1;
+    private int j = 1;
+    public String s1 = "Hi, ";
+    private String s2 = "Hi, ";
+
+    public static void main(String[] args) {
+        InnerClass inner =
+                new DiffResultAfterSameOperationInnerClasses().new InnerClass();
+        if (!inner.test()) {
+            throw new AssertionError("Different results after same calculation");
+        }
+    }
+
+    class InnerClass {
+        public boolean test() {
+            i += i += 1;
+            j += j += 1;
+
+            s1 += s1 += "dude";
+            s2 += s2 += "dude";
+
+            System.out.println("s1 = " + s1);
+            System.out.println("s2 = " + s2);
+
+            return (i == j && i == 3 &&
+                    s1.equals(s2) && s1.endsWith("Hi, Hi, dude"));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/7199823/InnerClassCannotBeVerified.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7199823
+ * @summary javac generates inner class that can't be verified
+ * @run main InnerClassCannotBeVerified
+ */
+
+import java.util.Arrays;
+import javax.tools.JavaFileObject;
+import java.net.URI;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+import javax.tools.JavaCompiler;
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import java.io.File;
+import java.io.IOException;
+
+public class InnerClassCannotBeVerified {
+
+    private static final String errorMessage =
+            "Compile error while compiling the following source:\n";
+
+    public static void main(String... args) throws Exception {
+        new InnerClassCannotBeVerified().run();
+    }
+
+    void run() throws Exception {
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        JavaSource source = new JavaSource();
+        JavacTask ct = (JavacTask)comp.getTask(null, null, null,
+                null, null, Arrays.asList(source));
+        try {
+            if (!ct.call()) {
+                throw new AssertionError(errorMessage +
+                        source.getCharContent(true));
+            }
+        } catch (Throwable ex) {
+            throw new AssertionError(errorMessage +
+                    source.getCharContent(true));
+        }
+        check();
+    }
+
+    private void check() throws IOException, ConstantPoolException {
+        File file = new File("Test$1.class");
+        ClassFile classFile = ClassFile.read(file);
+        boolean inheritsFromObject =
+                classFile.getSuperclassName().equals("java/lang/Object");
+        boolean implementsNoInterface = classFile.interfaces.length == 0;
+        boolean noMethods = classFile.methods.length == 0;
+        if (!(inheritsFromObject &&
+              implementsNoInterface &&
+              noMethods)) {
+            throw new AssertionError("The inner classes reused as " +
+                    "access constructor tag for this code must be empty");
+        }
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String internalSource =
+                              "public class Test {\n" +
+                              "    private static class Foo {}\n" +
+                              "    public static void main(String[] args){ \n" +
+                              "        new Foo();\n" +
+                              "        if(false) {\n" +
+                              "            new Runnable() {\n" +
+                              "                @Override\n" +
+                              "                public void run() {\n" +
+                              "                    System.out.println();\n" +
+                              "                }\n" +
+                              "            }.run();\n" +
+                              "        }\n" +
+                              "   }\n" +
+                              "}";
+        public JavaSource() {
+            super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return internalSource;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8005931
+ * @summary javac doesn't set ACC_STRICT for classes with package access
+ * @run main CheckACC_STRICTFlagOnPkgAccessClassTest
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+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.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.Method;
+
+import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
+
+public class CheckACC_STRICTFlagOnPkgAccessClassTest {
+
+    private static final String AssertionErrorMessage =
+        "All methods should have the ACC_STRICT access flag " +
+        "please check output";
+    private static final String CompilationErrorMessage =
+        "Error thrown when compiling the following source:\n";
+    private static final String offendingMethodErrorMessage =
+        "Method %s of class %s doesn't have the ACC_STRICT access flag";
+
+    JavaSource source = new JavaSource();
+
+    private List<String> errors = new ArrayList<>();
+
+    public static void main(String[] args)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        new CheckACC_STRICTFlagOnPkgAccessClassTest().run(comp);
+    }
+
+    private void run(JavaCompiler comp)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        compile(comp);
+        check();
+        if (errors.size() > 0) {
+            for (String error: errors) {
+                System.err.println(error);
+            }
+            throw new AssertionError(AssertionErrorMessage);
+        }
+    }
+
+    private void compile(JavaCompiler comp) {
+        JavacTask ct = (JavacTask)comp.getTask(null, null, null, null, null,
+                Arrays.asList(source));
+        try {
+            if (!ct.call()) {
+                throw new AssertionError(CompilationErrorMessage +
+                        source.getCharContent(true));
+            }
+        } catch (Throwable ex) {
+            throw new AssertionError(CompilationErrorMessage +
+                    source.getCharContent(true));
+        }
+    }
+
+    void check()
+        throws
+            IOException,
+            ConstantPoolException,
+            Descriptor.InvalidDescriptor {
+        ClassFile classFileToCheck = ClassFile.read(new File("Test.class"));
+
+        for (Method method : classFileToCheck.methods) {
+            if ((method.access_flags.flags & ACC_STRICT) == 0) {
+                errors.add(String.format(offendingMethodErrorMessage,
+                        method.getName(classFileToCheck.constant_pool),
+                        classFileToCheck.getName()));
+            }
+        }
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String source = "strictfp class Test {" +
+                "    Test(){}" +
+                "    void m(){}" +
+                "}";
+
+        public JavaSource() {
+            super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+}
--- a/test/tools/javac/Diagnostics/6799605/T6799605.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/Diagnostics/6799605/T6799605.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,4 +1,4 @@
-T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.incompatible.eq.upper.bounds: T, compiler.misc.type.captureof: 1, ?, T6799605<T>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
 T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
 T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?))}
 3 errors
--- a/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java	Sun Feb 17 16:44:55 2013 -0500
@@ -40,14 +40,17 @@
         IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
         IMPORTRETENTION("import java.lang.annotation.Retention;\n" +
                         "\nimport java.lang.annotation.RetentionPolicy;\n"),
+        IMPORTSTMTS("import java.lang.annotation.*;\n"),
         REPEATABLE("\n@Repeatable(FooContainer.class)\n"),
         CONTAINER("@interface FooContainer {\n" +"  Foo[] value();\n}\n"),
         BASE("@interface Foo {}\n"),
+        BASEANNO("@Foo"),
         REPEATABLEANNO("\n@Foo() @Foo()"),
         DEPRECATED("\n@Deprecated"),
         DOCUMENTED("\n@Documented"),
         INHERITED("\n@Inherited"),
-        RETENTION("@Retention(RetentionPolicy.#VAL)\n");
+        RETENTION("@Retention(RetentionPolicy.#VAL)\n"),
+        TARGET("\n@Target(#VAL)\n");
 
         private String val;
 
@@ -69,6 +72,7 @@
     public static final String template =
             "/*PACKAGE*/\n" +
             "//pkg test;\n\n" +
+            "/*ANNODATA*/\n" + // import statements, declaration of Foo/FooContainer
             "/*TYPE*/ //class\n" +
             "class #ClassName {\n" +
             "  /*FIELD*/ //instance var\n" +
@@ -97,7 +101,11 @@
             "interface TestInterface {}\n\n" +
             "/*TYPE*/\n" +
             "/*ANNOTATION_TYPE*/\n" +
-            "@interface TestAnnotationType{}\n";
+            "@interface TestAnnotationType{}\n" +
+            "class TestPkg {}\n" +
+            "class TestTypeAnno </*TYPE_PARAMETER*/ T extends Object> {\n" +
+            "  String /*TYPE_USE*/[] arr;\n" +
+            "}";
 
     // Create and compile FileObject using values for className and contents
     public static boolean compileCode(String className, String contents,
@@ -150,3 +158,4 @@
         }
     }
 }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug      7195131
+ * @author   sogoel
+ * @summary  Combo test for all possible combinations for Target values
+ * @build    Helper
+ * @compile  TargetAnnoCombo.java TestCaseGenerator.java
+ * @run main TargetAnnoCombo
+ */
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+/*
+ * TargetAnnoCombo gets a list of test case numbers using TestCaseGenerator.
+ * For each of the test case number, @Target sets for base and container annotations
+ * are determined, source files are generated, compiled, and the result is verified
+ * based on if the @Target set for base and container is a positive or negative combination.
+ *
+ * @Target sets for base and container annotations are determined using a bit mapping of
+ * 10 ElementType enum constants defined in JDK8.
+ *
+ * Bit      Target value
+ *  0  "ElementType.ANNOTATION_TYPE"
+ *  1  "ElementType.CONSTRUCTOR"
+ *  2  "ElementType.FIELD"
+ *  3  "ElementType.LOCAL_VARIABLE"
+ *  4  "ElementType.METHOD"
+ *  5  "ElementType.TYPE"
+ *  6  "ElementType.PARAMETER"
+ *  7  "ElementType.PACKAGE"
+ *  8  "ElementType.TYPE_USE"
+ *  9  "ElementType.TYPE_PARAMETER"
+ *
+ * Group 1:
+ * 20 bits mapping, representing a test case number, is used for all target set
+ * combinations ( 0 to 1048575 ) including empty @Target sets => @Target({}).
+ * From this 20 bits, 10 bits are for base followed by 10 bits for container
+ * where each bit maps to an ElementType enum constant defined in JDK8.
+ *
+ * Examples:
+ * Test case number: 4, binary: 100 => container=100, base=[], container=["ElementType.FIELD"]
+ * Test case number: 1003575, binary: 11110101000000110111 => base=1111010100, container=0000110111;
+ *                   base=["ElementType.PARAMETER", "ElementType.TYPE_USE", "ElementType.METHOD", "ElementType.FIELD", "ElementType.PACKAGE", "ElementType.TYPE_PARAMETER"],
+ *                   container=["ElementType.TYPE", "ElementType.METHOD", "ElementType.ANNOTATION_TYPE", "ElementType.CONSTRUCTOR", "ElementType.FIELD"]
+ *
+ * In the following groups, no @Target set is represented by null.
+ * Group 2:
+ * @Target is not defined on base.
+ * Target sets for container are determined using the 10-bit binary number
+ * resulting in 1024 test cases, mapping them to test case numbers from
+ * 1048576 to (1048576 + 1023) => 1048576 to 1049599.
+ *
+ * Example:
+ * Test case number: 1048587 => 1048587 - 1048576 = test case 11 in Group 2, binary: 1011 =>
+ *                   base = null,
+ *                   container = ["ElementType.ANNOTATION_TYPE","ElementType.CONSTRUCTOR","ElementType.LOCAL_VARIABLE"]
+ *
+ * Group 3:
+ * @Target is not defined on container
+ * Target sets for base are determined using the 10-bit binary number
+ * resulting in 1024 test cases, mapping them to test case numbers from
+ * 1049600 to (1049600 + 1023) => 1049600 to 1050623.
+ *
+ * Example:
+ * Test case number: 1049708 => 1049708 - 1049600 = test case 108 in Group 3, binary: 1101100 =>
+ *                   base = ["ElementType.FIELD", "ElementType.LOCAL_VARIABLE", "ElementType.TYPE", "ElementType.PARAMETER"],
+ *                   container = null
+ *
+ * For the above group, test case number: 1049855 gives compiler error, JDK-8006547 filed
+ *
+ * Group 4:
+ * @Target not defined for both base and container annotations.
+ *
+ * This is the last test and corresponds to test case number 1050624. base=null, container=null
+ *
+ * Examples to run this test:
+ * 1. Run a specific test case number:
+ *    ${JTREG} -DTestCaseNum=10782 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 2. Run specific number of tests:
+ *    ${JTREG} -DNumberOfTests=4 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 3. Run specific number of tests with a seed:
+ *    ${JTREG} -DNumberOfTests=4 -DTestSeed=-972894659 -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 4. Run tests in default mode (number of tests = 1000):
+ *    ${JTREG} -DTestMode=DEFAULT -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ * 5. Run all tests (FULL mode):
+ *    ${JTREG} -DTestMode=FULL -samevm -jdk:${JAVA_TEST} -reportDir ${REPORT} -workDir ${WORK} TargetAnnoCombo.java
+ *
+ */
+
+public class TargetAnnoCombo {
+    int errors = 0;
+    static final String TESTPKG = "testpkg";
+    /*
+     *  Set it to true to get more debug information including base and
+     *  container target sets for a given test case number
+     */
+    static final boolean DEBUG = false;
+
+    // JDK 5/6/7/8 Targets
+    static final String[] targetVals = {"ElementType.ANNOTATION_TYPE",
+      "ElementType.CONSTRUCTOR", "ElementType.FIELD",
+      "ElementType.LOCAL_VARIABLE", "ElementType.METHOD",
+      "ElementType.TYPE", "ElementType.PARAMETER",
+      "ElementType.PACKAGE", "ElementType.TYPE_USE",
+      "ElementType.TYPE_PARAMETER"};
+
+    // TYPE_USE and TYPE_PARAMETER (added in JDK8) are not part of default Target set
+    static final int DEFAULT_TARGET_CNT = 8;
+
+    public static void main(String args[]) throws Exception {
+
+        /* maxTestNum = (base and container combinations of targetVals elems [0 - 1048575 combos])
+         *              + (combinations where base or container has no Target [1024 combos])
+         *              + (no -1 even though 1st test is number 0 as last test is where both
+         *                 base and container have no target)
+         */
+
+        int maxTestNum = (int)Math.pow(2, 2*targetVals.length) + 2*(int)Math.pow(2, targetVals.length);
+        TestCaseGenerator tcg = new TestCaseGenerator(maxTestNum);
+        TargetAnnoCombo tac = new TargetAnnoCombo();
+
+        int testCtr = 0;
+        int testCase = -1;
+        while ( (testCase=tcg.getNextTestCase()) != -1 ) {
+            tac.executeTestCase(testCase, maxTestNum);
+            testCtr++;
+        }
+
+        System.out.println("Total tests run: " + testCtr);
+        if (tac.errors > 0)
+            throw new Exception(tac.errors + " errors found");
+    }
+
+    /*
+     * For given testCase, determine the base and container annotation Target sets,
+     * get if testCase should compile, get test source file(s), get compilation result and verify.
+     *
+     */
+    private void executeTestCase(int testCase, int maxTestNum) {
+
+        // Determine base and container annotation Target sets for the testCase
+        Set<String> baseAnnoTarget = null;
+        Set<String> conAnnoTarget = null;
+
+        //Number of base and container combinations [0 - 1048575 combos]
+        int baseContCombos = (int)Math.pow(2, 2*targetVals.length);
+        //Number of either base or container combinations when one of them has no @Target [1024 combos]
+        int targetValsCombos = (int)Math.pow(2, targetVals.length);
+
+        if (testCase >= baseContCombos) {
+            //Base annotation do not have @Target
+            if (testCase < baseContCombos + targetValsCombos) {
+                baseAnnoTarget = null;
+                conAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos));
+            } else if (testCase < baseContCombos + 2*targetValsCombos) {
+                //Container annotation do not have @Target
+                baseAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos - targetValsCombos));
+                conAnnoTarget = null;
+            } else {
+                //Both Base and Container annotation do not have @Target
+                baseAnnoTarget = null;
+                conAnnoTarget = null;
+            }
+        } else {
+            //TestCase number is represented as 10-bits for base followed by container bits
+            String bin = Integer.toBinaryString(testCase);
+            String base="", cont=bin;
+            if (bin.length() > targetVals.length){
+                base = bin.substring(0, bin.length() - targetVals.length);
+                cont = bin.substring(bin.length() - targetVals.length,bin.length());
+            }
+            baseAnnoTarget = getSetFromBitVec(base);
+            conAnnoTarget = getSetFromBitVec(cont);
+        }
+
+        debugPrint("Test case number = " + testCase + " => binary = " + Integer.toBinaryString(testCase));
+        debugPrint(" => baseAnnoTarget = " + baseAnnoTarget);
+        debugPrint(" => containerAnnoTarget = " + conAnnoTarget);
+
+        // Determine if a testCase should compile or not
+        String className = "TC" + testCase;
+        boolean shouldCompile = isValidSubSet(baseAnnoTarget, conAnnoTarget);
+
+        // Get test source file(s)
+        Iterable<? extends JavaFileObject> files = getFileList(className, baseAnnoTarget,
+                conAnnoTarget, shouldCompile);
+
+        // Get result of compiling test src file(s)
+        boolean result = getCompileResult(className, shouldCompile, files);
+
+        // List test src code if test fails
+        if(!result) {
+            System.out.println("FAIL: Test " + testCase);
+            try {
+                for (JavaFileObject f: files) {
+                    System.out.println("File: " + f.getName() + "\n" + f.getCharContent(true));
+                }
+            } catch (IOException ioe) {
+                System.out.println("Exception: " + ioe);
+            }
+        } else {
+            debugPrint("PASS: Test " + testCase);
+        }
+    }
+
+    // Get a Set<String> based on bits that are set to 1
+    public Set<String> getSetFromBitVec(String bitVec) {
+        Set<String> ret = new HashSet<>();
+        char[] bit = bitVec.toCharArray();
+        for (int i=bit.length-1, j=0; i>=0; i--, j++){
+            if (bit[i] == '1') {
+                ret.add(targetVals[j]);
+            }
+        }
+        return ret;
+    }
+
+    // Compile the test source file(s) and return test result
+    private boolean getCompileResult(String className, boolean shouldCompile,
+            Iterable<? extends JavaFileObject> files) {
+
+        DiagnosticCollector<JavaFileObject> diagnostics =
+                new DiagnosticCollector<JavaFileObject>();
+        Helper.compileCode(diagnostics, files);
+
+        // Test case pass or fail
+        boolean ok = false;
+
+        String errMesg = "";
+        int numDiags = diagnostics.getDiagnostics().size();
+
+        if (numDiags == 0) {
+            if (shouldCompile) {
+                debugPrint("Test passed, compiled as expected.");
+                ok = true;
+            } else {
+                errMesg = "Test failed, compiled unexpectedly.";
+                ok = false;
+            }
+        } else {
+            if (shouldCompile) {
+                // did not compile
+                errMesg = "Test failed, did not compile.";
+                ok = false;
+            } else {
+                // Error in compilation as expected
+                String expectedErrKey = "compiler.err.invalid.repeatable." +
+                        "annotation.incompatible.target";
+                for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
+                    if((d.getKind() == Diagnostic.Kind.ERROR) &&
+                        d.getCode().contains(expectedErrKey)) {
+                        // Error message as expected
+                        debugPrint("Error message as expected.");
+                        ok = true;
+                        break;
+                    } else {
+                        // error message is incorrect
+                        ok = false;
+                    }
+                }
+                if (!ok) {
+                    errMesg = "Incorrect error received when compiling " +
+                        className + ", expected: " + expectedErrKey;
+                }
+            }
+        }
+
+        if(!ok) {
+            error(errMesg);
+            for (Diagnostic<?> d : diagnostics.getDiagnostics())
+                System.out.println(" Diags: " + d);
+        }
+        return ok;
+    }
+
+    private void debugPrint(String string) {
+        if(DEBUG)
+            System.out.println(string);
+    }
+
+    // Create src code and corresponding JavaFileObjects
+    private Iterable<? extends JavaFileObject> getFileList(String className,
+            Set<String> baseAnnoTarget, Set<String> conAnnoTarget,
+            boolean shouldCompile) {
+
+        String srcContent = "";
+        String pkgInfoContent = "";
+        String template = Helper.template;
+        String baseTarget = "", conTarget = "";
+
+        String target = Helper.ContentVars.TARGET.getVal();
+        if(baseAnnoTarget != null) {
+            baseTarget = target.replace("#VAL", baseAnnoTarget.toString())
+                                  .replace("[", "{").replace("]", "}");
+        }
+        if(conAnnoTarget != null) {
+            conTarget = target.replace("#VAL", conAnnoTarget.toString())
+                                 .replace("[", "{").replace("]", "}");
+        }
+
+        String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() +
+                          conTarget +
+                          Helper.ContentVars.CONTAINER.getVal() +
+                          baseTarget +
+                          Helper.ContentVars.REPEATABLE.getVal() +
+                          Helper.ContentVars.BASE.getVal();
+
+        JavaFileObject pkgInfoFile = null;
+
+        /*
+         *  If shouldCompile = true and no @Target is specified for container annotation,
+         *  then all 8 ElementType enum constants are applicable as targets for
+         *  container annotation.
+         */
+        if(shouldCompile && conAnnoTarget == null) {
+            //conAnnoTarget = new HashSet<String>(Arrays.asList(targetVals));
+            conAnnoTarget = getDefaultTargetSet();
+        }
+
+        if(shouldCompile) {
+            boolean isPkgCasePresent = new ArrayList<String>(conAnnoTarget).contains("ElementType.PACKAGE");
+            String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + " " + Helper.ContentVars.BASEANNO.getVal();
+            for(String s: conAnnoTarget) {
+                s = s.replace("ElementType.","");
+                String replaceStr = "/*"+s+"*/";
+                if(s.equalsIgnoreCase("PACKAGE")) {
+                    //Create packageInfo file
+                    String pkgInfoName = TESTPKG + "." + "package-info";
+                    pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData;
+                    pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent);
+                } else {
+                    template = template.replace(replaceStr, repeatableAnno);
+                    //srcContent = template.replace("#ClassName",className);
+                    if(!isPkgCasePresent) {
+                        srcContent = template.replace("/*ANNODATA*/", annoData).replace("#ClassName",className);
+                    } else {
+                        replaceStr = "/*PACKAGE*/";
+                        srcContent = template.replace(replaceStr, "package " + TESTPKG + ";")
+                                     .replace("#ClassName", className);
+                    }
+                }
+            }
+        } else {
+            // For invalid cases, compilation should fail at declaration site
+            template = "class #ClassName {}";
+            srcContent = annoData + template.replace("#ClassName",className);
+        }
+        JavaFileObject srcFile = Helper.getFile(className, srcContent);
+        Iterable<? extends JavaFileObject> files = null;
+        if(pkgInfoFile != null)
+            files = Arrays.asList(pkgInfoFile,srcFile);
+        else
+            files = Arrays.asList(srcFile);
+        return files;
+    }
+
+    private Set<String> getDefaultTargetSet() {
+        Set<String> defaultSet = new HashSet<>();
+        int ctr = 0;
+        for(String s : targetVals) {
+            if(ctr++ < DEFAULT_TARGET_CNT) {
+                defaultSet.add(s);
+            }
+        }
+        return defaultSet;
+    }
+
+    private boolean isValidSubSet(Set<String> baseAnnoTarget, Set<String> conAnnoTarget) {
+        /*
+         *  RULE 1: conAnnoTarget should be a subset of baseAnnoTarget
+         *  RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere
+         *         - Empty sets for both is valid
+         *         - Empty baseTarget set is invalid with non-empty conTarget set
+         *         - Non-empty baseTarget set is valid with empty conTarget set
+         *  RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets
+         *         - No @Target for both is valid
+         *         - No @Target for baseTarget set with @Target conTarget set is valid
+         *         - @Target for baseTarget set with no @Target for conTarget is invalid
+         */
+
+
+        /* If baseAnno has no @Target, Foo can be either applied to @Target specified for container annotation
+         * else will be applicable for all default targets if no @Target is present for container annotation.
+         * In both cases, the set will be a valid set with no @Target for base annotation
+         */
+        if(baseAnnoTarget == null) {
+            if(conAnnoTarget == null) return true;
+            return !(conAnnoTarget.contains("ElementType.TYPE_USE") || conAnnoTarget.contains("ElementType.TYPE_PARAMETER"));
+        }
+
+        Set<String> tempBaseSet = new HashSet<>(baseAnnoTarget);
+        // If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default
+        if(baseAnnoTarget.contains("ElementType.TYPE")) {
+            tempBaseSet.add("ElementType.ANNOTATION_TYPE");
+        }
+
+        /*
+         * If containerAnno has no @Target, only valid case if baseAnnoTarget has all targets defined
+         * else invalid set
+         */
+        if(conAnnoTarget == null) {
+            return (tempBaseSet.containsAll(getDefaultTargetSet()));
+        }
+
+        // At this point, neither conAnnoTarget or baseAnnoTarget are null
+        if(conAnnoTarget.size() == 0) return true;
+
+        // At this point, conAnnoTarget is non-empty
+        if (baseAnnoTarget.size() == 0) return false;
+
+        // At this point, neither conAnnoTarget or baseAnnoTarget are empty
+        return tempBaseSet.containsAll(conAnnoTarget);
+    }
+
+    void error(String msg) {
+        System.out.println("ERROR: " + msg);
+        errors++;
+    }
+
+    // Lists the start and end range for the given set of target vals
+    void showGroups() {
+        //Group 1: All target set combinations ( 0 to 1048575 ) including empty @Target sets => @Target({})
+        int grpEnd1 = (int)Math.pow(2, 2*targetVals.length) - 1;
+        System.out.println("[Group 1]: 0 - " + grpEnd1);
+
+        //Group 2: @Target not defined for base annotation ( 1048576 - 1049599 ).
+        System.out.print("[Group 2]: " + (grpEnd1 + 1) + " - ");
+        int grpEnd2 = grpEnd1 + 1 + (int)Math.pow(2, targetVals.length) - 1;
+        System.out.println(grpEnd2);
+
+        //Group 3: @Target not defined for container annotation ( 1049600 - 1050623 ).
+        System.out.print("[Group 3]: " + (grpEnd2 + 1) + " - ");
+        int grpEnd3 = grpEnd2 + 1 + (int)Math.pow(2, targetVals.length) - 1;
+        System.out.println(grpEnd3);
+
+        //Group 4: @Target not defined for both base and container annotations ( 1050624 ).
+        System.out.println("[Group 4]: " + (grpEnd3 + 1));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/repeatingAnnotations/combo/TestCaseGenerator.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+
+/* System properties:
+ * NumberOfTests, TestMode, and TestCaseNum are mutually exclusive
+ * TestSeed will be used only with NumberOfTests or TestMode, otherwise it will be ignored
+ * -DNumberOfTests=[0 to 2^20+2^11+1]
+ * -DTestMode=[FULL|DEFAULT]
+ * -DTestSeed=[seedNumber]
+ * -DTestCaseNum=[0 to 2^20+2^11+1]
+ */
+public class TestCaseGenerator {
+    // Total number of tests to be run
+    int numberOfTests = -1;
+    //Single test case
+    int testCaseNum = -1;
+    //Seed used to generate test cases
+    int testSeed;
+
+    int maxTestNum;
+    Random randNum;
+
+    // used in getNextTestCase
+    int curTestNum;
+    int testCompletedCount;
+    HashSet<Integer> uniqueTestSet;
+
+    static final int DEFAULT_TEST_COUNT = 250;
+
+    /*
+     *  Get parameter values from command line to set numberOfTests, testCaseNum,
+     *  and testSeed
+     */
+    public TestCaseGenerator(int maxTestNum) {
+        this.maxTestNum = maxTestNum;
+
+        // Set values for variables based on input from command line
+
+        // TestMode system property
+        String testModeVal = System.getProperty("TestMode");
+        if(testModeVal != null && !testModeVal.isEmpty()) {
+            switch (testModeVal.toUpperCase()) {
+            case "FULL":
+                numberOfTests = maxTestNum;
+                break;
+            case "DEFAULT":
+                numberOfTests = DEFAULT_TEST_COUNT;
+                break;
+            default:
+                System.out.println("Invalid property value " + testModeVal +
+                        " for numberOfTests. Possible range: 0 to " +
+                        maxTestNum + ". Ignoring property");
+                numberOfTests = -1;
+            }
+        }
+
+        // NumberOfTests system property
+        String numTestsStr = System.getProperty("NumberOfTests");
+        if(numTestsStr != null && !numTestsStr.isEmpty()) {
+            int numTests = -1;
+            try {
+                numTests = Integer.parseInt(numTestsStr);
+                if (numTests < 0 || numTests > maxTestNum) {
+                    throw new NumberFormatException();
+                }
+            } catch(NumberFormatException nfe) {
+                System.out.println("Invalid NumberOfTests property value " +
+                        numTestsStr + ". Possible range: 0 to " + maxTestNum +
+                        "Reset to default: " + DEFAULT_TEST_COUNT);
+                numTests = DEFAULT_TEST_COUNT;
+            }
+
+            if (numberOfTests != -1 && numTests != -1) {
+                System.out.println("TestMode and NumberOfTests cannot be set together. Ignoring TestMode.");
+            }
+            numberOfTests = numTests;
+        }
+
+        // TestSeed system property
+        String seedVal = System.getProperty("TestSeed");
+        if(seedVal != null && !seedVal.isEmpty()) {
+            try {
+                testSeed = Integer.parseInt(seedVal);
+            } catch(NumberFormatException nfe) {
+                Random srand = new Random();
+                testSeed = srand.nextInt();
+            }
+        } else {
+            Random srand = new Random();
+            testSeed = srand.nextInt();
+        }
+
+        // TestCaseNum system property
+        String testNumStr = System.getProperty("TestCaseNum");
+        if(testNumStr != null && !testNumStr.isEmpty()) {
+            try {
+                testCaseNum = Integer.parseInt(testNumStr);
+                if (testCaseNum < 0 || testCaseNum > maxTestNum) {
+                    throw new NumberFormatException();
+                }
+            } catch(NumberFormatException nfe) {
+                System.out.println("Invalid TestCaseNumber property value " +
+                        testNumStr + ". Possible value in range: 0 to " +
+                        maxTestNum + ". Defaulting to last test case.");
+                testCaseNum = maxTestNum;
+            }
+
+            if ( numberOfTests != -1) {
+                System.out.println("TestMode or NumberOfTests cannot be set along with TestCaseNum. Ignoring TestCaseNumber.");
+                testCaseNum = -1;
+            }
+        }
+
+        if (numberOfTests == -1 && testCaseNum == -1) {
+            numberOfTests = DEFAULT_TEST_COUNT;
+            System.out.println("Setting TestMode to default, will run " + numberOfTests + "tests.");
+        }
+
+        /*
+         *  By this point in code, we will have:
+         *  - testSeed: as per TestSeed or a Random one
+         *  - numberOfTests to run or -1 to denote not set
+         *  - testCaseNum to run or -1 to denote not set
+         */
+
+        /*
+         * If numberOfTests = maxTestNum, all tests are to be run,
+         * so no randNum will be required
+         */
+        if (numberOfTests != -1 && numberOfTests < maxTestNum) {
+            System.out.println("Seed = " + testSeed);
+            randNum = new Random(testSeed);
+            uniqueTestSet = new HashSet<>();
+        }
+
+        testCompletedCount = 0;
+        // to be used to keep sequential count when running all tests
+        curTestNum = 0;
+    }
+
+    /*
+     * returns next test case number to run
+     * returns -1 when there are no more tests to run
+     */
+    public int getNextTestCase() {
+        if (testCaseNum != -1) {
+            int nextTC = testCaseNum;
+            testCaseNum = -1;
+            return nextTC;
+        }
+        if (++testCompletedCount <= numberOfTests) {
+            if (numberOfTests == maxTestNum) {
+                //all the tests need to be run, so just return
+                //next test case sequentially
+                return curTestNum++;
+            } else {
+                int nextTC = -1;
+                // Ensuring unique test are run
+                while(!uniqueTestSet.add(nextTC = randNum.nextInt(maxTestNum))) {
+                }
+                return nextTC;
+            }
+        }
+        return -1;
+    }
+}
--- a/test/tools/javac/annotations/typeAnnotations/TargetTypes.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/TargetTypes.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/TypeProcOnly.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/api/AnnotatedArrayOrder.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/api/ArrayCreationTree.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/api/ArrayPositionConsistency.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -174,22 +174,20 @@
 
             String sourceBase = new String("@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainedBy( AC.class )\n" +
+            "@Repeatable( AC.class )\n" +
             "@interface A { }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainerFor(A.class)\n" +
             "@interface AC { A[] value(); }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainedBy( BC.class )\n" +
+            "@Repeatable( BC.class )\n" +
             "@interface B { }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainerFor(B.class)\n" +
             "@interface BC { B[] value(); } \n\n" +
 
             "@Retention("+retentn+")\n" +
@@ -198,12 +196,11 @@
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
-            "@ContainedBy(DC.class)\n" +
+            "@Repeatable(DC.class)\n" +
             "@interface D { }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
-            "@ContainerFor(D.class) \n" +
             "@interface DC { D[] value(); }\n\n");
 
         // Test case sources with sample generated source.
--- a/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -171,32 +171,29 @@
 
             String sourceBase = new String("@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainedBy( AC.class )\n" +
+            "@Repeatable( AC.class )\n" +
             "@interface A { }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainerFor(A.class)\n" +
             "@interface AC { A[] value(); }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainedBy( BC.class )\n" +
+            "@Repeatable( BC.class )\n" +
             "@interface B { }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,_OTHER_})\n" +
-            "@ContainerFor(B.class)\n" +
             "@interface BC { B[] value(); } \n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
-            "@ContainedBy(DC.class)\n" +
+            "@Repeatable(DC.class)\n" +
             "@interface D { }\n\n" +
 
             "@Retention("+retentn+")\n" +
             "@Target({TYPE_USE,TYPE_PARAMETER,_OTHER_})\n" +
-            "@ContainerFor(D.class) \n" +
             "@interface DC { D[] value(); }\n\n");
 
         // Test case sources with sample generated source
--- a/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/LazyConstantValue.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008077
+ * @summary Type annotations in a lazy constant need to be attributed
+ *   in the correct order.
+ * @author Werner Dietl
+ * @compile LazyConstantValue.java
+ */
+
+import java.lang.annotation.*;
+
+class ClassA {
+    Object o = ClassB.lcv;
+}
+
+class ClassB {
+    static final String[] lcv = new @TA String[0];
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/TypeVariable.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008077
+ * @summary Type annotations on a type variable, where the bound of
+ *   the type variable is also annotated, need to be processed correctly.
+ * @author Werner Dietl
+ * @compile TypeVariable.java
+ */
+
+import java.lang.annotation.*;
+
+class TypeVariable {
+    <TV extends  @TA Object> TV cast(TV p) {
+        return (@TA TV) p;
+    }
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA {}
+
--- a/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/failures/VoidGenericMethod.java	Sun Feb 17 16:44:55 2013 -0500
@@ -21,6 +21,8 @@
  * questions.
  */
 
+import java.lang.annotation.*;
+
 /*
  * @test
  * @bug 6843077 8006775
@@ -29,7 +31,8 @@
  * @compile/fail VoidGenericMethod.java
  */
 class VoidGenericMethod {
-  public <T> @A void method() { }
+  public @A <T> void method() { }
 }
 
+@Target(ElementType.TYPE_USE)
 @interface A { }
--- a/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/failures/target/DotClass.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,13 +1,5 @@
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.ElementType.TYPE_PARAMETER;
-import static java.lang.annotation.ElementType.TYPE_USE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +28,14 @@
  * @compile/fail/ref=DotClass.out -XDrawDiagnostics DotClass.java
  */
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.TYPE_PARAMETER;
+import static java.lang.annotation.ElementType.TYPE_USE;
+
 @Target({TYPE_USE, TYPE_PARAMETER, TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @interface A {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/newlocations/Lambda.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008077
+ * @summary new type annotation location: lambda expressions
+ * @compile Lambda.java
+ * @author Werner Dietl
+ */
+
+import java.lang.annotation.*;
+
+public class Lambda {
+
+    interface LambdaInt {
+        <S, T> void generic(S p1, T p2);
+    }
+
+    static class LambdaImpl implements LambdaInt {
+        <S, T> LambdaImpl(S p1, T p2) {}
+        public <S, T> void generic(S p1, T p2) {}
+    }
+
+    LambdaInt getMethodRefTA(LambdaImpl r) {
+        return r::<@TA Object, @TB Object>generic;
+    }
+
+    LambdaInt getConstructorRefTA() {
+        return LambdaImpl::<@TA Object, @TB Object>new;
+    }
+
+}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TB { }
--- a/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/newlocations/RepeatingTypeAnnotations.java	Sun Feb 17 16:44:55 2013 -0500
@@ -120,7 +120,6 @@
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
 @interface RTA { }
 
-@ContainerFor(RTA.class)
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
 @interface RTAs {
     RTA[] value();
--- a/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/newlocations/Varargs.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,6 +1,5 @@
-
 /*
- * Copyright (c) 2008 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +21,6 @@
  * questions.
  */
 
-import java.lang.annotation.*;
-
 /*
  * @test
  * @summary test acceptance of varargs annotations
@@ -31,6 +28,8 @@
  * @compile Varargs.java
  */
 
+import java.lang.annotation.*;
+
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
 @interface A {}
 
--- a/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/packageanno/PackageProcessor.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/Anno.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/MyClass.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/packageanno/mypackage/package-info.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -241,8 +241,8 @@
         sb.append("\n@Repeatable(RTAs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTA {}");
         sb.append("\n@Repeatable(RTBs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTB {}");
 
-        sb.append("\n@ContainerFor(RTA.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTAs { RTA[] value(); }");
-        sb.append("\n@ContainerFor(RTB.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTBs { RTB[] value(); }");
+        sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTAs { RTA[] value(); }");
+        sb.append("\n@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTBs { RTB[] value(); }");
 
         sb.append("\n@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})");
         sb.append("\n@interface Decl {}");
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8008077
+ * @summary Test population of reference info for lambda expressions
+ * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java
+ * @run main Driver Lambda
+ * @author Werner Dietl
+ */
+
+import static com.sun.tools.classfile.TypeAnnotation.TargetType.*;
+
+public class Lambda {
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String returnMethodRef1() {
+        return
+                "class Lambda {" +
+                "  public String getName() { return \"Lambda!\"; }" +
+                "}" +
+
+                "class Test {" +
+                "  java.util.function.Function<Lambda, String> lambda() {" +
+                "    return @TA @TB Lambda::getName;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TC", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TD", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 }),
+        @TADescription(annotation = "TE", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnMethodRef2() {
+        return
+                "class Lambda<S, T> {" +
+                "  public String getName() { return \"Lambda!\"; }" +
+                "}" +
+
+                "class Test {" +
+                "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
+                "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::getName;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "CTA", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "CTB", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "CTC", type = METHOD_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnMethodRef3() {
+        return
+                "class Lambda<S, T> {" +
+                "  public String getName() { return \"Lambda!\"; }" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTA {" +
+                "  String value();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTB {" +
+                "  int age();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTC {" +
+                "  String name();" +
+                "}" +
+
+                "class Test {" +
+                "  java.util.function.Function<Lambda<Integer, Float>, String> lambda() {" +
+                "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::getName;" +
+                "  }" +
+                "}";
+    }
+
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE)
+    })
+    public String returnConstructorRef1() {
+        return
+                "class Lambda {" +
+                "  Lambda() { }" +
+                "}" +
+
+                "class Test {" +
+                "  Runnable lambda() {" +
+                "    return @TA @TB Lambda::new;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TC", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "TD", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 }),
+        @TADescription(annotation = "TE", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnConstructorRef2() {
+        return
+                "class Lambda<S, T> {" +
+                "  Lambda() { }" +
+                "}" +
+
+                "class Test {" +
+                "  Runnable lambda() {" +
+                "    return @TA Lambda<@TB @TC Integer, @TD @TE Float>::new;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "CTA", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "CTB", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 0 }),
+        @TADescription(annotation = "CTC", type = CONSTRUCTOR_REFERENCE,
+                offset = ReferenceInfoUtil.IGNORE_VALUE,
+                genericLocation = { 3, 1 })
+    })
+    public String returnConstructorRef3() {
+        return
+                "class Lambda<S, T> {" +
+                "  Lambda() { }" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTA {" +
+                "  String value();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTB {" +
+                "  int age();" +
+                "}" +
+
+                "@Target(ElementType.TYPE_USE)" +
+                "@interface CTC {" +
+                "  String name();" +
+                "}" +
+
+                "class Test {" +
+                "  Runnable lambda() {" +
+                "    return @CTA(\"x\") Lambda<@CTB(age = 5) Integer, @CTC(name = \"y\") Float>::new;" +
+                "  }" +
+                "}";
+    }
+
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 0),
+        @TADescription(annotation = "TB", type = METHOD_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 1)
+    })
+    public String returnMethodRefTA1() {
+        return
+                "interface Lambda {" +
+                "  <S, T> void generic(S p1, T p2);" +
+                "}" +
+
+                "class LambdaImpl implements Lambda {" +
+                "  public <S, T> void generic(S p1, T p2) {}" +
+                "}" +
+
+                "class Test {" +
+                "  Lambda lambda(LambdaImpl r) {" +
+                "    return r::<@TA Object, @TB Object>generic;" +
+                "  }" +
+                "}";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 0),
+        @TADescription(annotation = "TB", type = CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
+                 offset = ReferenceInfoUtil.IGNORE_VALUE,
+                 typeIndex = 1)
+    })
+    public String returnConstructorRefTA2() {
+        return
+                "interface Lambda {" +
+                "  <S, T> void generic(S p1, T p2);" +
+                "}" +
+
+                "class LambdaImpl implements Lambda {" +
+                "  <S, T> LambdaImpl(S p1, T p2) {}" +
+                "  public <S, T> void generic(S p1, T p2) {}" +
+                "}" +
+
+                "class Test {" +
+                "  Lambda lambda() {" +
+                "    return LambdaImpl::<@TA Object, @TB Object>new;" +
+                "  }" +
+                "}";
+    }
+
+}
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -93,6 +93,28 @@
     }
 
     @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1),
+        @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1)
+    })
+    public String methodParamAsArray2() {
+        return "void test(Object b, @TA @TB String [] a) { }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1),
+        @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1),
+        @TADescription(annotation = "TC", type = METHOD_FORMAL_PARAMETER,
+                genericLocation = { 0, 0 }, paramIndex = 1)
+    })
+    public String methodParamAsArray3() {
+        return "void test(Object b, @TA @TB @TC String [] a) { }";
+    }
+
+    @TADescriptions({
         @TADescription(annotation = "TA", type = METHOD_FORMAL_PARAMETER, paramIndex = 1),
         @TADescription(annotation = "TB", type = METHOD_FORMAL_PARAMETER,
                 genericLocation = { 0, 0 }, paramIndex = 1),
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,118 +31,170 @@
  */
 public class TypeCasts {
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String returnObject() {
         return "Object returnObject() { return (@TA String)null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE),
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TC", type = CAST,
-                genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0, 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String returnObjectArray() {
         return "Object returnObjectArray() { return (@TC String @TA [] @TB [])null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String returnObjectGeneric() {
         return "Object returnObjectGeneric() { return (@TA List<@TB String>)null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String returnPrim() {
         return "Object returnPrim() { return (@TA int)0; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String returnPrimArray() {
         return "Object returnPrimArray() { return (@TB int @TA [])null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String initObject() {
         return "void initObject() { Object a =  (@TA String)null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String initObjectArray() {
         return "void initObjectArray() { Object a = (@TB String @TA [])null; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String initObjectGeneric() {
         return "void initObjectGeneric() { Object a = (@TA List<@TB String>)null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String initPrim() {
         return "void initPrim() { Object a =  (@TA int)0; }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String initPrimArray() {
         return "void initPrimArray() { Object a = (@TB int @TA [])null; }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     public String eqtestObject() {
         return "void eqtestObject() { if (null == (@TA String)null); }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String eqtestObjectArray() {
         return "void eqtestObjectArray() { if (null == (@TB String @TA [])null); }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 3, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String eqtestObjectGeneric() {
         return "void eqtestObjectGeneric() { if (null == (@TA List<@TB String >)null); }";
     }
 
-    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE)
+    @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+            typeIndex = 0)
     // compiler optimizes away compile time constants casts
     public String eqtestPrim() {
         return "void eqtestPrim(int a) { if (0 == (@TA int)a); }";
     }
 
     @TADescriptions({
-        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE),
+        @TADescription(annotation = "TA", type = CAST, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0),
         @TADescription(annotation = "TB", type = CAST,
-                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE)
+                genericLocation = { 0, 0 }, offset = ReferenceInfoUtil.IGNORE_VALUE,
+                typeIndex = 0)
     })
     public String eqtestPrimArray() {
         return "void eqtestPrimArray() { if (null == (@TB int @TA [])null); }";
     }
 
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 0),
+        @TADescription(annotation = "TB", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1),
+        @TADescription(annotation = "TC", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1,
+                genericLocation = {3, 0})
+    })
+    public String intersection1() {
+        return "void intersection() { Object o = (@TA String & @TB Comparable<@TC String>) null; }";
+    }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 0),
+        @TADescription(annotation = "TB", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1),
+        @TADescription(annotation = "TC", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 1,
+                genericLocation = {3, 0}),
+        @TADescription(annotation = "TD", type = CAST,
+                offset = ReferenceInfoUtil.IGNORE_VALUE, typeIndex = 2),
+    })
+    public String intersection2() {
+        return "void intersection() { Object o = (@TA String & @TB Comparable<@TC String> & @TD CharSequence) null; }";
+    }
 }
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/api/8007344/Test.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007344
+ * @summary javac may not make tree end positions and/or doc comments
+ *          available to processors and listeners
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor
+ * @run main Test
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Set;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+
+import com.sun.source.doctree.DocCommentTree;
+import com.sun.source.tree.*;
+import com.sun.source.util.DocTrees;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.Pretty;
+import com.sun.tools.javac.util.Position;
+
+/** Doc comment: Test */
+public class Test {
+    public static final int EXPECT_DOC_COMMENTS = 3;
+
+    /** Doc comment: main */
+    public static void main(String... args) throws Exception {
+        PrintWriter out = new PrintWriter(System.err);
+        try {
+            new Test(out).run();
+        } finally {
+            out.flush();
+        }
+    }
+
+    PrintWriter out;
+    int errors;
+
+    Test(PrintWriter out) {
+        this.out = out;
+    }
+
+    /** Doc comment: run */
+    void run() throws Exception {
+        File testSrc = new File(System.getProperty("test.src"));
+        File thisFile = new File(testSrc, getClass().getName() + ".java");
+        JavacTool javac = JavacTool.create();
+        StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
+        fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
+        Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjects(thisFile);
+        testAnnoProcessor(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
+        testTaskListener(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void testAnnoProcessor(JavacTool javac, StandardJavaFileManager fm,
+            Iterable<? extends JavaFileObject> files, PrintWriter out,
+            int expectedDocComments) {
+        out.println("Test annotation processor");
+        JavacTask task = javac.getTask(out, fm, null, null, null, files);
+        AnnoProc ap = new AnnoProc(DocTrees.instance(task));
+        task.setProcessors(Arrays.asList(ap));
+        task.call();
+        ap.checker.checkDocComments(expectedDocComments);
+    }
+
+    void testTaskListener(JavacTool javac, StandardJavaFileManager fm,
+            Iterable<? extends JavaFileObject> files, PrintWriter out,
+            int expectedDocComments) {
+        out.println("Test task listener");
+        JavacTask task = javac.getTask(out, fm, null, null, null, files);
+        TaskListnr tl = new TaskListnr(DocTrees.instance(task));
+        task.addTaskListener(tl);
+        task.call();
+        tl.checker.checkDocComments(expectedDocComments);
+    }
+
+    void error(String msg) {
+        out.println("Error: " + msg);
+        errors++;
+    }
+
+    class AnnoProc extends JavacTestingAbstractProcessor {
+        Checker checker;
+
+        AnnoProc(DocTrees trees) {
+            checker = new Checker(trees);
+        }
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            for (Element e : roundEnv.getRootElements()) {
+                checker.scan(checker.trees.getPath(e), null);
+            }
+            return true;
+        }
+    }
+
+    class TaskListnr implements TaskListener {
+        Checker checker;
+
+        TaskListnr(DocTrees trees) {
+            checker = new Checker(trees);
+        }
+
+        public void started(TaskEvent e) {
+            if (e.getKind() == TaskEvent.Kind.ANALYZE)
+                checker.scan(new TreePath(e.getCompilationUnit()), null);
+        }
+
+        public void finished(TaskEvent e) {
+        }
+    }
+
+    class Checker extends TreePathScanner<Void,Void> {
+        DocTrees trees;
+        SourcePositions srcPosns;
+
+        int docComments = 0;
+
+        Checker(DocTrees trees) {
+            this.trees = trees;
+            srcPosns = trees.getSourcePositions();
+        }
+
+        @Override
+        public Void scan(Tree tree, Void ignore) {
+            if (tree != null) {
+                switch (tree.getKind()) {
+                    // HACK: Workaround 8007350
+                    // Some tree nodes do not have endpos set
+                    case ASSIGNMENT:
+                    case BLOCK:
+                    case IDENTIFIER:
+                    case METHOD_INVOCATION:
+                        break;
+
+                    default:
+                        checkEndPos(getCurrentPath().getCompilationUnit(), tree);
+                }
+            }
+            return super.scan(tree, ignore);
+        }
+
+        @Override
+        public Void visitClass(ClassTree tree, Void ignore) {
+            checkComment();
+            return super.visitClass(tree, ignore);
+        }
+
+        @Override
+        public Void visitMethod(MethodTree tree, Void ignore) {
+            checkComment();
+            return super.visitMethod(tree, ignore);
+        }
+
+        @Override
+        public Void visitVariable(VariableTree tree, Void ignore) {
+            checkComment();
+            return super.visitVariable(tree, ignore);
+        }
+
+        void checkComment() {
+            DocCommentTree dc = trees.getDocCommentTree(getCurrentPath());
+            if (dc != null) {
+                out.println("comment: " + dc.toString().replaceAll("\\s+", " "));
+                docComments++;
+            }
+        }
+
+        void checkEndPos(CompilationUnitTree unit, Tree tree) {
+            long sp = srcPosns.getStartPosition(unit, tree);
+            long ep = srcPosns.getEndPosition(unit, tree);
+            if (sp >= 0 && ep == Position.NOPOS) {
+                error("endpos not set for " + tree.getKind()
+                        + " " + Pretty.toSimpleString(((JCTree) tree))
+                        +", start:" + sp);
+            }
+        }
+
+        void checkDocComments(int expected) {
+            if (docComments != expected) {
+                error("Unexpected number of doc comments received: "
+                        + docComments + ", expected: " + expected);
+            }
+        }
+
+    }
+}
--- a/test/tools/javac/api/T6306137.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/api/T6306137.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,9 @@
  * @test
  * @bug     6306137
  * @summary JSR 199: encoding option doesn't affect standard file manager
+ * @compile -encoding utf-8 T6306137.java
+ * @run main T6306137
  * @author  Peter von der Ahé
- * @ignore
- *    Need to make the contentCache in JavacFileManager be aware of changes to the encoding.
- *    Need to propogate -source (and -encoding?) down to the JavacFileManager
  */
 
 import java.io.File;
--- a/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java	Sun Feb 17 16:44:55 2013 -0500
@@ -23,7 +23,6 @@
 
 /*
  * @test
- * @ignore awaits for VM support
  * @summary  check that javac does not generate bridge methods for defaults
  */
 
--- a/test/tools/javac/diags/examples/CantApplyDiamond1.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/diags/examples/CantApplyDiamond1.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 // key: compiler.err.prob.found.req
 // key: compiler.misc.cant.apply.diamond.1
-// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
+// key: compiler.misc.incompatible.eq.upper.bounds
 // key: compiler.misc.diamond
 
 class CantApplyDiamond1<X> {
--- a/test/tools/javac/diags/examples/InferredDoNotConformToEq.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/diags/examples/InferredDoNotConformToEq.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 // key: compiler.err.cant.apply.symbol
 // key: compiler.misc.inferred.do.not.conform.to.eq.bounds
+// options: -source 7 -Xlint:-options
 
 import java.util.*;
 
--- a/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/diags/examples/InferredDoNotConformToUpper.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 // key: compiler.err.cant.apply.symbol
 // key: compiler.misc.inferred.do.not.conform.to.upper.bounds
+// options: -source 7 -Xlint:-options
 
 import java.util.*;
 
--- a/test/tools/javac/diags/examples/WhereFreshTvar.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/diags/examples/WhereFreshTvar.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 // key: compiler.misc.where.fresh.typevar
 // key: compiler.misc.where.description.typevar
 // key: compiler.err.prob.found.req
-// key: compiler.misc.inferred.do.not.conform.to.upper.bounds
+// key: compiler.misc.inconvertible.types
 // options: -XDdiags=where,simpleNames
 // run: simple
 
@@ -33,5 +33,5 @@
 class WhereFreshTvar {
     <T extends List<T>> T m() {}
 
-    { List<String> ls = m(); }
+    { Object o = (List<String>)m(); }
 }
--- a/test/tools/javac/generics/7015430/T7015430.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/7015430/T7015430.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,14 +1,14 @@
-T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
 T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
 T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.RuntimeException>
 T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<E>
+T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable<java.lang.Exception>
 T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, <init>, java.lang.Iterable<E>, java.lang.Iterable, kindname.class, T7015430
 T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
 T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
--- a/test/tools/javac/generics/7151802/T7151802.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/7151802/T7151802.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802
-T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<Z>
+T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.Object>
 T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo<Z>, T7151802.Foo, kindname.class, T7151802
 T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802
 T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo<java.lang.String>
--- a/test/tools/javac/generics/diamond/neg/Neg06.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/diamond/neg/Neg06.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,2 +1,2 @@
-Neg06.java:16:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.String, java.lang.Number))
+Neg06.java:16:37: compiler.err.prob.found.req: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: Neg06.CFoo), (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String, java.lang.Number))
 1 error
--- a/test/tools/javac/generics/inference/6278587/T6278587Neg.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/6278587/T6278587Neg.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,11 @@
 
 /*
  * @test
- * @bug     6278587
+ * @bug     6278587 8007464
  * @summary Inference broken for subtypes of subtypes of F-bounded types
  * @author  Peter von der Ah\u00e9
- * @compile/fail T6278587Neg.java
+ * @compile/fail -source 7 T6278587Neg.java
+ * @compile T6278587Neg.java
  */
 
 public abstract class T6278587Neg {
--- a/test/tools/javac/generics/inference/6638712/T6638712d.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/6638712/T6638712d.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,2 +1,2 @@
-T6638712d.java:16: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, (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.String, java.lang.Integer)
+T6638712d.java:16: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, (compiler.misc.incompatible.eq.lower.bounds: U, java.lang.String, java.lang.Integer)
 1 error
--- a/test/tools/javac/generics/inference/6638712/T6638712e.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/6638712/T6638712e.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,2 +1,2 @@
-T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Object, java.lang.Boolean,java.lang.Object)
+T6638712e.java:17:27: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.Object, java.lang.Boolean,java.lang.Object)
 1 error
--- a/test/tools/javac/generics/inference/7154127/T7154127.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/7154127/T7154127.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,8 +1,9 @@
 /**
  * @test /nodynamiccopyright/
- * @bug 7154127
+ * @bug 7154127 8007464
  * @summary Inference cleanup: remove bound check analysis from visitors in Types.java
- * @compile/fail/ref=T7154127.out -XDrawDiagnostics T7154127.java
+ * @compile/fail/ref=T7154127.out -Xlint:-options -source 7 -XDrawDiagnostics T7154127.java
+ * @compile T7154127.java
  */
 class T7154127 {
 
--- a/test/tools/javac/generics/inference/7154127/T7154127.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/7154127/T7154127.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,2 +1,2 @@
-T7154127.java:19:49: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: Y, T7154127.D,T7154127.B<U>)
+T7154127.java:20:49: compiler.err.prob.found.req: (compiler.misc.incompatible.upper.bounds: Y, T7154127.B<U>,T7154127.D)
 1 error
--- a/test/tools/javac/generics/inference/7177306/T7177306a.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/7177306/T7177306a.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,4 +1,4 @@
-T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<E>
+T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<java.lang.Object>
 T7177306a.java:13:33: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, java.util.List<E>, java.util.List, kindname.class, T7177306a
 T7177306a.java:13:33: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7177306a, T7177306a<java.lang.Object>
 - compiler.err.warnings.and.werror
--- a/test/tools/javac/generics/inference/7177306/T7177306e.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/7177306/T7177306e.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,8 +1,9 @@
 /**
  * @test /nodynamiccopyright/
- * @bug 7177306
+ * @bug 7177306 8007464
  * @summary Regression: unchecked method call does not erase return type
- * @compile/fail/ref=T7177306e.out -XDrawDiagnostics T7177306e.java
+ * @compile/fail/ref=T7177306e.out -source 7 -Xlint:-options -XDrawDiagnostics T7177306e.java
+ * @compile/fail T7177306e.java
  */
 
 import java.util.List;
--- a/test/tools/javac/generics/inference/7177306/T7177306e.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/inference/7177306/T7177306e.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,2 +1,2 @@
-T7177306e.java:15:9: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.util.List<?>, java.util.List<compiler.misc.type.captureof: 1, ?>)
+T7177306e.java:16:9: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.util.List<?>, java.util.List<compiler.misc.type.captureof: 1, ?>)
 1 error
--- a/test/tools/javac/generics/odersky/BadTest4.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/generics/odersky/BadTest4.java	Sun Feb 17 16:44:55 2013 -0500
@@ -23,11 +23,12 @@
 
 /*
  * @test
- * @ bug
+ * @bug 8007464
  * @summary Negative regression test from odersky
  * @author odersky
  *
- * @compile/fail  BadTest4.java
+ * @compile/fail -source 7 BadTest4.java
+ * @compile BadTest4.java
  */
 
 class BadTest4 {
--- a/test/tools/javac/lambda/LambdaCapture06.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/LambdaCapture06.java	Sun Feb 17 16:44:55 2013 -0500
@@ -23,7 +23,6 @@
 
 /*
  * @test
- * @ignore investigate as to whether code generation fails
  * @bug 8003280
  * @summary Add lambda tests
  *  Compiler crash when local inner class nested inside lambda captures local variables from enclosing scope
--- a/test/tools/javac/lambda/LambdaExpr15.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/LambdaExpr15.java	Sun Feb 17 16:44:55 2013 -0500
@@ -23,7 +23,6 @@
 
 /*
  * @test
- * @ignore investigate as to whether code generation fails
  * @bug 8003280
  * @summary Add lambda tests
  *  check that nested inner class in statement lambdas don't get corrupted return statements
--- a/test/tools/javac/lambda/TargetType14.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/TargetType14.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,2 +1,2 @@
-TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.lower.bounds: java.lang.Integer, java.lang.String)
+TargetType14.java:20:29: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.lower.bounds: X, java.lang.Integer, java.lang.String)
 1 error
--- a/test/tools/javac/lambda/TargetType20.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/TargetType20.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,10 +1,33 @@
 /*
- * @test /nodynamiccopyright/
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
  * @bug 8003280
  * @summary Add lambda tests
  *  complex case of lambda return type that depends on generic method
  *          inference variable
- * @compile/fail/ref=TargetType20.out -XDrawDiagnostics TargetType20.java
+ * @compile -XDrawDiagnostics TargetType20.java
  */
 import java.util.*;
 
--- a/test/tools/javac/lambda/TargetType20.out	Mon Feb 04 18:08:53 2013 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-TargetType20.java:19:10: compiler.err.cant.apply.symbol: kindname.method, call, TargetType20.SAM2<Z>,TargetType20.SAM2<Z>, @428,@459, kindname.class, TargetType20.Test, (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.String, java.lang.String,java.lang.Object)
-1 error
--- a/test/tools/javac/lambda/TargetType28.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/TargetType28.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,3 +1,2 @@
-TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.String)
-TargetType28.java:21:33: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.eq.bounds: java.lang.Number, java.lang.Number,java.lang.Integer)
-2 errors
+TargetType28.java:20:32: compiler.err.prob.found.req: (compiler.misc.incompatible.eq.upper.bounds: X, java.lang.String,X, java.lang.Object,java.lang.Number)
+1 error
--- a/test/tools/javac/lambda/TargetType50.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/TargetType50.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,9 +1,32 @@
 /*
- * @test /nodynamiccopyright/
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
  * @bug 8003280
  * @summary Add lambda tests
  *  bad stuck check for method reference leads to javac crash
- * @compile/fail/ref=TargetType50.out -XDrawDiagnostics TargetType50.java
+ * @compile TargetType50.java
  */
 import java.util.*;
 
@@ -17,7 +40,7 @@
         static <Z> Sink<Z> make() { return null; }
     }
 
-    <Y, S extends Sink<Y>> List<Y> m(Factory<S> factory) {  }
+    <Y, S extends Sink<Y>> List<Y> m(Factory<S> factory) { return null; }
 
     void test() {
         List<?> l1 = m(Sink::new);
--- a/test/tools/javac/lambda/TargetType50.out	Mon Feb 04 18:08:53 2013 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-TargetType50.java:25:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
-TargetType50.java:26:28: compiler.err.prob.found.req: (compiler.misc.inferred.do.not.conform.to.upper.bounds: TargetType50.Sink<java.lang.Object>, TargetType50.Sink<java.lang.String>)
-2 errors
--- a/test/tools/javac/lambda/TargetType51.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/TargetType51.java	Sun Feb 17 16:44:55 2013 -0500
@@ -23,7 +23,9 @@
 
 /*
  * @test
- * @summary smoke test for combinator-like stuck analysis
+ * @bug 8005244
+ * @summary Implement overload resolution as per latest spec EDR
+ *          smoke test for combinator-like stuck analysis
  * @author  Maurizio Cimadamore
  * @compile TargetType51.java
  */
--- a/test/tools/javac/lambda/TargetType52.java	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/TargetType52.java	Sun Feb 17 16:44:55 2013 -0500
@@ -1,6 +1,8 @@
 /*
  * @test /nodynamiccopyright/
- * @summary uncatched sam conversion failure exception lead to javac crash
+ * @bug 8005244
+ * @summary Implement overload resolution as per latest spec EDR
+ *          uncatched sam conversion failure exception lead to javac crash
  * @compile/fail/ref=TargetType52.out -XDrawDiagnostics TargetType52.java
  */
 class TargetType52 {
--- a/test/tools/javac/lambda/TargetType52.out	Mon Feb 04 18:08:53 2013 -0500
+++ b/test/tools/javac/lambda/TargetType52.out	Sun Feb 17 16:44:55 2013 -0500
@@ -1,2 +1,2 @@
-TargetType52.java:15:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @444, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>))
+TargetType52.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType52.FI<? extends java.lang.CharSequence,? extends java.util.ArrayList<? extends java.lang.CharSequence>>, @525, kindname.class, TargetType52, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: TargetType52.FI<java.lang.CharSequence,java.util.ArrayList<? extends java.lang.CharSequence>>))
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType53.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          smoke test for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType53.java
+ */
+import java.util.*;
+import java.util.stream.*;
+import java.util.function.*;
+
+class TargetType53 {
+
+    <P> List<List<P>> perm(List<P> l) { return null; }
+
+    void g(List<List<UnaryOperator<IntStream>>> l) { }
+
+    void test() {
+        List<List<UnaryOperator<IntStream>>> l =
+            perm(Arrays.asList(s -> s.sorted()));
+        g(perm(Arrays.asList(s -> s.sorted())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType54.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          smoke test for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType54.java
+ */
+import java.util.stream.*;
+import java.util.*;
+import static java.util.stream.Collectors.*;
+
+class TargetType54 {
+    void test(Stream<Integer> si) {
+        List<Integer> l1 = si.collect(toList());
+        List<Integer> l2 = si.collect(toCollection(ArrayList::new));
+        m(si.collect(toList()));
+        m(si.collect(toCollection(ArrayList::new)));
+    }
+
+    void m(List<Integer> l) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType55.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference
+ *          support smoke test for graph inference
+ * @compile TargetType55.java
+ */
+import java.util.function.*;
+
+class TargetType55  {
+
+    <R> void m(Function<Integer, R> collector) { }
+
+    <T, D> Function<T, Integer> g(D d, BinaryOperator<D> reducer) { return null; }
+
+    public void test() {
+        m(g((Integer)null, (x,y)->1));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType56.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          smoke test for graph inference
+ * @compile TargetType56.java
+ */
+class TargetType56 {
+    <Z> Z m(Z z) { return null; }
+
+    void test() {
+        double d1 = m(1);
+        double d2 = m((Integer)null);
+        double d3 = m(m(1));
+        double d4 = m(m((Integer)null));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType57.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          more smoke tests for graph inference
+ * @compile/fail/ref=TargetType57.out -XDrawDiagnostics TargetType57.java
+ */
+import java.util.*;
+import java.util.function.*;
+
+class TargetType57 {
+
+    void test(List<Integer> list) {
+        m(list, s -> s.intValue(), s -> s.nonExistentMethod());
+    }
+
+    <U, R, S_IN, S_OUT> R m(List<S_IN> list,
+                        Function<S_IN, S_OUT> f1,
+                        Function<S_OUT, R> f2) { return null; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType57.out	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,2 @@
+TargetType57.java:14:42: compiler.err.cant.resolve.location.args: kindname.method, nonExistentMethod, , , (compiler.misc.location.1: kindname.variable, s, java.lang.Integer)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType58.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          more smoke tests for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType58.java
+ */
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.*;
+
+class TargetType58 {
+
+    void test(List<Integer> li) {
+        g(li, s -> s.substream(200), Collections.emptyList());
+    }
+
+    <T, U, S_OUT extends Stream<U>,
+            I extends Iterable<U>> Collection<U> g(Collection<T> coll, Function<Stream<T>, S_OUT> f, I i) {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType59.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          more smoke tests for graph inference
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType59.java
+ */
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.*;
+
+class TargetType59 {
+
+    <T, R> Collector<T, R> m(Supplier<? extends R> supplier, BiConsumer<R, T> accumulator) {
+        return null;
+    }
+
+    <T, C extends Collection<T>> Collector<T,C> test1(Supplier<C> collectionFactory) {
+        return m(collectionFactory, Collection::add);
+    }
+
+    Collector<String, StringBuilder> test2(Supplier<StringBuilder> sb) {
+        return m(sb, StringBuilder::append);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType61.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          check that new wildcards inference strategy doesn't run into 7190296
+ * @compile TargetType61.java
+ */
+class TargetType61 {
+
+    interface Stream<T> {
+        void forEach(Sink<? super T> sink);
+    }
+
+    interface Sink<T> {
+        void put(T t);
+    }
+
+    public boolean add(CharSequence s) { return false; }
+
+    public void addAll(Stream<? extends CharSequence> stream) {
+        stream.forEach(this::add);
+        stream.forEach(e -> { add(e); });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType62.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8007464
+ * @summary Add graph inference support
+ *          check that new wildcards inference strategy doesn't run into 7190296
+ * @ignore  awaits stream API: 800NNNN
+ * @compile TargetType62.java
+ */
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.*;
+
+class TargetType61 {
+
+    Collector test(Function<Integer, Integer> classifier) {
+        return g(classifier, TreeMap::new, m(HashSet::new));
+    }
+
+    <R> Collector<Integer, R> m(Supplier<R> s) { return null; }
+
+    <T, K, D, M extends Map<K, D>>
+            Collector<T, M> g(Function<T, K> classifier, Supplier<M> mapFactory, Collector<T, D> downstream) { return null; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lib/DPrinter.java	Sun Feb 17 16:44:55 2013 -0500
@@ -0,0 +1,1332 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.tools.FileObject;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.javac.code.Annotations;
+import com.sun.tools.javac.code.Attribute;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.code.Printer;
+import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.Scope.CompoundScope;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.TypeTag;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.Pretty;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+
+
+/**
+ * Debug printer for javac internals, for when toString() just isn't enough.
+ *
+ * <p>
+ * The printer provides an API to generate structured views of javac objects,
+ * such as AST nodes, symbol, types and annotations. Various aspects of the
+ * output can be configured, such as whether to show nulls, empty lists, or
+ * a compressed representation of the source code. Visitors are used to walk
+ * object hierarchies, and can be replaced with custom visitors if the default
+ * visitors are not flexible enough.
+ *
+ * <p>
+ * In general, nodes are printed with an initial line identifying the node
+ * followed by indented lines for the child nodes. Currently, graphs are
+ * represented by printing a spanning subtree.
+ *
+ * <p>
+ * The printer can be accessed via a simple command-line utility,
+ * which makes it easy to see the internal representation of source code,
+ * such as simple test programs, during the compilation pipeline.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+
+public class DPrinter {
+    protected final PrintWriter out;
+    protected final Trees trees;
+    protected Printer printer;
+    protected boolean showEmptyItems = true;
+    protected boolean showNulls = true;
+    protected boolean showPositions = false;
+    protected boolean showSrc;
+    protected boolean showTreeSymbols;
+    protected boolean showTreeTypes;
+    protected int maxSrcLength = 32;
+    protected Locale locale = Locale.getDefault();
+    protected static final String NULL = "#null";
+
+    // <editor-fold defaultstate="collapsed" desc="Configuration">
+
+    public static DPrinter instance(Context context) {
+        DPrinter dp = context.get(DPrinter.class);
+        if (dp == null) {
+            dp = new DPrinter(context);
+        }
+        return dp;
+
+    }
+
+    protected DPrinter(Context context) {
+        context.put(DPrinter.class, this);
+        out = context.get(Log.outKey);
+        trees = JavacTrees.instance(context);
+    }
+
+    public DPrinter(PrintWriter out, Trees trees) {
+        this.out = out;
+        this.trees = trees;
+    }
+
+    public DPrinter emptyItems(boolean showEmptyItems) {
+        this.showEmptyItems = showEmptyItems;
+        return this;
+    }
+
+    public DPrinter nulls(boolean showNulls) {
+        this.showNulls = showNulls;
+        return this;
+    }
+
+    public DPrinter positions(boolean showPositions) {
+        this.showPositions = showPositions;
+        return this;
+    }
+
+    public DPrinter source(boolean showSrc) {
+        this.showSrc = showSrc;
+        return this;
+    }
+
+    public DPrinter source(int maxSrcLength) {
+        this.showSrc = true;
+        this.maxSrcLength = maxSrcLength;
+        return this;
+    }
+
+    public DPrinter treeSymbols(boolean showTreeSymbols) {
+        this.showTreeSymbols = showTreeSymbols;
+        return this;
+    }
+
+    public DPrinter treeTypes(boolean showTreeTypes) {
+        this.showTreeTypes = showTreeTypes;
+        return this;
+    }
+
+    public DPrinter typeSymbolPrinter(Printer p) {
+        printer = p;
+        return this;
+    }
+
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="Printing">
+
+    protected enum Details {
+        /** A one-line non-recursive summary */
+        SUMMARY,
+        /** Multi-line, possibly recursive. */
+        FULL
+    };
+
+    public void printAnnotations(String label, Annotations annotations) {
+        printAnnotations(label, annotations, Details.FULL);
+    }
+
+    protected void printAnnotations(String label, Annotations annotations, Details details) {
+        if (annotations == null) {
+            printNull(label);
+        } else {
+            // no SUMMARY format currently available to use
+
+            // use reflection to get at private fields
+            Object DECL_NOT_STARTED = getField(null, Annotations.class, "DECL_NOT_STARTED");
+            Object DECL_IN_PROGRESS = getField(null, Annotations.class, "DECL_IN_PROGRESS");
+            Object attributes = getField(annotations, Annotations.class, "attributes");
+            Object type_attributes = getField(annotations, Annotations.class, "type_attributes");
+
+            if (!showEmptyItems) {
+                if (attributes instanceof List && ((List) attributes).isEmpty()
+                        && attributes != DECL_NOT_STARTED
+                        && attributes != DECL_IN_PROGRESS
+                        && type_attributes instanceof List && ((List) type_attributes).isEmpty())
+                    return;
+            }
+
+            printString(label, hashString(annotations));
+
+            indent(+1);
+            if (attributes == DECL_NOT_STARTED)
+                printString("attributes", "DECL_NOT_STARTED");
+            else if (attributes == DECL_IN_PROGRESS)
+                printString("attributes", "DECL_IN_PROGRESS");
+            else if (attributes instanceof List)
+                printList("attributes", (List) attributes);
+            else
+                printObject("attributes", attributes, Details.SUMMARY);
+
+            if (attributes instanceof List)
+                printList("type_attributes", (List) type_attributes);
+            else
+                printObject("type_attributes", type_attributes, Details.SUMMARY);
+            indent(-1);
+        }
+    }
+
+    public void printAttribute(String label, Attribute attr) {
+        if (attr == null) {
+            printNull(label);
+        } else {
+            printString(label, attr.getClass().getSimpleName());
+
+            indent(+1);
+            attr.accept(attrVisitor);
+            indent(-1);
+        }
+    }
+
+    public void printFileObject(String label, FileObject fo) {
+        if (fo == null) {
+            printNull(label);
+        } else {
+            printString(label, fo.getName());
+        }
+    }
+
+    protected <T> void printImplClass(T item, Class<? extends T> stdImplClass) {
+        if (item.getClass() != stdImplClass)
+            printString("impl", item.getClass().getName());
+    }
+
+    public void printInt(String label, int i) {
+        printString(label, String.valueOf(i));
+    }
+
+    public void printList(String label, List<?> list) {
+        if (list == null) {
+             printNull(label);
+        } else if (!list.isEmpty() || showEmptyItems) {
+            printString(label, "[" + list.size() + "]");
+
+            indent(+1);
+            int i = 0;
+            for (Object item: list) {
+                printObject(String.valueOf(i++), item, Details.FULL);
+            }
+            indent(-1);
+        }
+    }
+
+    public void printName(String label, Name name) {
+        if (name == null) {
+            printNull(label);
+        } else {
+            printString(label, name.toString());
+        }
+    }
+
+    public void printNull(String label) {
+        if (showNulls)
+            printString(label, NULL);
+    }
+
+    protected void printObject(String label, Object item, Details details) {
+        if (item == null) {
+            printNull(label);
+        } else if (item instanceof Attribute) {
+            printAttribute(label, (Attribute) item);
+        } else if (item instanceof Symbol) {
+            printSymbol(label, (Symbol) item, details);
+        } else if (item instanceof Type) {
+            printType(label, (Type) item, details);
+        } else if (item instanceof JCTree) {
+            printTree(label, (JCTree) item);
+        } else if (item instanceof List) {
+            printList(label, (List) item);
+        } else if (item instanceof Name) {
+            printName(label, (Name) item);
+        } else {
+            printString(label, String.valueOf(item));
+        }
+    }
+
+    public void printScope(String label, Scope scope) {
+        printScope(label, scope, Details.FULL);
+    }
+
+    public void printScope(String label, Scope scope, Details details) {
+        if (scope == null) {
+            printNull(label);
+        } else {
+            switch (details) {
+                case SUMMARY: {
+                    indent();
+                    out.print(label);
+                    out.print(": [");
+                    String sep = "";
+                    for (Symbol sym: scope.getElements()) {
+                        out.print(sep);
+                        out.print(sym.name);
+                        sep = ",";
+                    }
+                    out.println("]");
+                    break;
+                }
+
+                case FULL: {
+                    indent();
+                    out.println(label);
+
+                    indent(+1);
+                    printImplClass(scope, Scope.class);
+                    printSymbol("owner", scope.owner, Details.SUMMARY);
+                    printScope("next", scope.next, Details.SUMMARY);
+                    printObject("shared", getField(scope, Scope.class, "shared"), Details.SUMMARY);
+                    if (scope instanceof CompoundScope) {
+                        printObject("subScopes",
+                                getField(scope, CompoundScope.class, "subScopes"),
+                                Details.FULL);
+                    } else {
+                        for (Symbol sym : scope.getElements()) {
+                            printSymbol(sym.name.toString(), sym, Details.SUMMARY);
+                        }
+                    }
+                    indent(-1);
+                    break;
+                }
+            }
+        }
+    }
+
+    public void printSource(String label, JCTree tree) {
+        printString(label, Pretty.toSimpleString(tree, maxSrcLength));
+    }
+
+    public void printString(String label, String text) {
+        indent();
+        out.print(label);
+        out.print(": ");
+        out.print(text);
+        out.println();
+    }
+
+    public void printSymbol(String label, Symbol symbol) {
+        printSymbol(label, symbol, Details.FULL);
+    }
+
+    protected void printSymbol(String label, Symbol sym, Details details) {
+        if (sym == null) {
+            printNull(label);
+        } else {
+            switch (details) {
+            case SUMMARY:
+                printString(label, toString(sym));
+                break;
+
+            case FULL:
+                indent();
+                out.print(label);
+                out.println(": " +
+                        info(sym.getClass(),
+                            String.format("0x%x--%s", sym.kind, Kinds.kindName(sym)),
+                            sym.getKind())
+                        + " " + sym.name
+                        + " " + hashString(sym));
+
+                indent(+1);
+                if (showSrc) {
+                    JCTree tree = (JCTree) trees.getTree(sym);
+                    if (tree != null)
+                        printSource("src", tree);
+                }
+                printString("flags", String.format("0x%x--%s",
+                        sym.flags_field, Flags.toString(sym.flags_field)));
+                printObject("completer", sym.completer, Details.SUMMARY); // what if too long?
+                printSymbol("owner", sym.owner, Details.SUMMARY);
+                printType("type", sym.type, Details.SUMMARY);
+                printType("erasure", sym.erasure_field, Details.SUMMARY);
+                sym.accept(symVisitor, null);
+                printAnnotations("annotations", sym.annotations, Details.SUMMARY);
+                indent(-1);
+            }
+        }
+    }
+
+    protected String toString(Symbol sym) {
+        return (printer != null) ? printer.visit(sym, locale) : String.valueOf(sym);
+    }
+
+    protected void printTree(String label, JCTree tree) {
+        if (tree == null) {
+            printNull(label);
+        } else {
+            indent();
+            String ext;
+            try {
+                ext = tree.getKind().name();
+            } catch (Throwable t) {
+                ext = "n/a";
+            }
+            out.print(label + ": " + info(tree.getClass(), tree.getTag(), ext));
+            if (showPositions) {
+                // We can always get start position, but to get end position
+                // and/or line+offset, we would need a JCCompilationUnit
+                out.print(" pos:" + tree.pos);
+            }
+            if (showTreeTypes && tree.type != null)
+                out.print(" type:" + toString(tree.type));
+            Symbol sym;
+            if (showTreeSymbols && (sym = TreeInfo.symbolFor(tree)) != null)
+                out.print(" sym:" + toString(sym));
+            out.println();
+
+            indent(+1);
+            if (showSrc) {
+                indent();
+                out.println("src: " + Pretty.toSimpleString(tree, maxSrcLength));
+            }
+            tree.accept(treeVisitor);
+            indent(-1);
+        }
+    }
+
+    public void printType(String label, Type type) {
+        printType(label, type, Details.FULL);
+    }
+
+    protected void printType(String label, Type type, Details details) {
+        if (type == null)
+            printNull(label);
+        else {
+            switch (details) {
+                case SUMMARY:
+                    printString(label, toString(type));
+                    break;
+
+                case FULL:
+                    indent();
+                    out.print(label);
+                    out.println(": " + info(type.getClass(), type.getTag(), type.getKind())
+                            + " " + hashString(type));
+
+                    indent(+1);
+                    printSymbol("tsym", type.tsym, Details.SUMMARY);
+                    printObject("constValue", type.constValue(), Details.SUMMARY);
+                    type.accept(typeVisitor, null);
+                    indent(-1);
+            }
+        }
+    }
+
+    protected String toString(Type type) {
+        return (printer != null) ? printer.visit(type, locale) : String.valueOf(type);
+    }
+
+    protected String hashString(Object obj) {
+        return String.format("#%x", obj.hashCode());
+    }
+
+    protected String info(Class<?> clazz, Object internal, Object external) {
+        return String.format("%s,%s,%s", clazz.getSimpleName(), internal, external);
+    }
+
+    private int indent = 0;
+
+    protected void indent() {
+        for (int i = 0; i < indent; i++) {
+            out.print("  ");
+        }
+    }
+
+    protected void indent(int n) {
+        indent += n;
+    }
+
+    protected Object getField(Object o, Class<?> clazz, String name) {
+        try {
+            Field f = clazz.getDeclaredField(name);
+            boolean prev = f.isAccessible();
+            f.setAccessible(true);
+            try {
+                return f.get(o);
+            } finally {
+                f.setAccessible(prev);
+            }
+        } catch (ReflectiveOperationException e) {
+            return e;
+        } catch (SecurityException e) {
+            return e;
+        }
+    }
+
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="JCTree visitor methods">
+
+    protected JCTree.Visitor treeVisitor = new TreeVisitor();
+
+    /**
+     * Default visitor class for JCTree (AST) objects.
+     */
+    public class TreeVisitor extends JCTree.Visitor {
+        @Override
+        public void visitTopLevel(JCCompilationUnit tree) {
+            printList("packageAnnotations", tree.packageAnnotations);
+            printTree("pid", tree.pid);
+            printList("defs", tree.defs);
+        }
+
+        @Override
+        public void visitImport(JCImport tree) {
+            printTree("qualid", tree.qualid);
+        }
+
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+            printName("name", tree.name);
+            printTree("mods", tree.mods);
+            printList("typarams", tree.typarams);
+            printTree("extending", tree.extending);
+            printList("implementing", tree.implementing);
+            printList("defs", tree.defs);
+        }
+
+        @Override
+        public void visitMethodDef(JCMethodDecl tree) {
+            printName("name", tree.name);
+            printTree("mods", tree.mods);
+            printTree("restype", tree.restype);
+            printList("typarams", tree.typarams);
+            printTree("recvparam", tree.recvparam);
+            printList("params", tree.params);
+            printList("thrown", tree.thrown);
+            printTree("defaultValue", tree.defaultValue);
+            printTree("body", tree.body);
+        }
+
+        @Override
+        public void visitVarDef(JCVariableDecl tree) {
+            printName("name", tree.name);
+            printTree("mods", tree.mods);
+            printTree("vartype", tree.vartype);
+            printTree("init", tree.init);
+        }
+
+        @Override
+        public void visitSkip(JCSkip tree) {
+        }
+
+        @Override
+        public void visitBlock(JCBlock tree) {
+            printList("stats", tree.stats);
+        }
+
+        @Override
+        public void visitDoLoop(JCDoWhileLoop tree) {
+            printTree("body", tree.body);
+            printTree("cond", tree.cond);
+        }
+
+        @Override
+        public void visitWhileLoop(JCWhileLoop tree) {
+            printTree("cond", tree.cond);
+            printTree("body", tree.body);
+        }
+
+        @Override
+        public void visitForLoop(JCForLoop tree) {
+            printList("init", tree.init);
+            printTree("cond", tree.cond);
+            printList("step", tree.step);
+            printTree("body", tree.body);
+        }
+
+        @Override
+        public void visitForeachLoop(JCEnhancedForLoop tree) {
+            printTree("var", tree.var);
+            printTree("expr", tree.expr);
+            printTree("body", tree.body);
+        }
+
+        @Override
+        public void visitLabelled(JCLabeledStatement tree) {
+            printTree("body", tree.body);
+        }
+
+        @Override
+        public void visitSwitch(JCSwitch tree) {
+            printTree("selector", tree.selector);
+            printList("cases", tree.cases);
+        }
+
+        @Override
+        public void visitCase(JCCase tree) {
+            printTree("pat", tree.pat);
+            printList("stats", tree.stats);
+        }
+
+        @Override
+        public void visitSynchronized(JCSynchronized tree) {
+            printTree("lock", tree.lock);
+            printTree("body", tree.body);
+        }
+
+        @Override
+        public void visitTry(JCTry tree) {
+            printList("resources", tree.resources);
+            printTree("body", tree.body);
+            printList("catchers", tree.catchers);
+            printTree("finalizer", tree.finalizer);
+        }
+
+        @Override
+        public void visitCatch(JCCatch tree) {
+            printTree("param", tree.param);
+            printTree("body", tree.body);
+        }
+
+        @Override
+        public void visitConditional(JCConditional tree) {
+            printTree("cond", tree.cond);
+            printTree("truepart", tree.truepart);
+            printTree("falsepart", tree.falsepart);
+        }
+
+        @Override
+        public void visitIf(JCIf tree) {
+            printTree("cond", tree.cond);
+            printTree("thenpart", tree.thenpart);
+            printTree("elsepart", tree.elsepart);
+        }
+
+        @Override
+        public void visitExec(JCExpressionStatement tree) {
+            printTree("expr", tree.expr);
+        }
+
+        @Override
+        public void visitBreak(JCBreak tree) {
+            printName("label", tree.label);
+        }
+
+        @Override
+        public void visitContinue(JCContinue tree) {
+            printName("label", tree.label);
+        }
+
+        @Override
+        public void visitReturn(JCReturn tree) {
+            printTree("expr", tree.expr);
+        }
+
+        @Override
+        public void visitThrow(JCThrow tree) {
+            printTree("expr", tree.expr);
+        }
+
+        @Override
+        public void visitAssert(JCAssert tree) {
+            printTree("cond", tree.cond);
+            printTree("detail", tree.detail);
+        }
+
+        @Override
+        public void visitApply(JCMethodInvocation tree) {
+            printList("typeargs", tree.typeargs);
+            printTree("meth", tree.meth);
+            printList("args", tree.args);
+        }
+
+        @Override
+        public void visitNewClass(JCNewClass tree) {
+            printTree("encl", tree.encl);
+            printList("typeargs", tree.typeargs);
+            printTree("clazz", tree.clazz);
+            printList("args", tree.args);
+            printTree("def", tree.def);
+        }
+
+        @Override
+        public void visitNewArray(JCNewArray tree) {
+            printList("annotations", tree.annotations);
+            printTree("elemtype", tree.elemtype);
+            printList("dims", tree.dims);
+            printList("dimAnnotations", tree.dimAnnotations);
+            printList("elems", tree.elems);
+        }
+
+        @Override
+        public void visitLambda(JCLambda tree) {
+            printTree("body", tree.body);
+            printList("params", tree.params);
+        }
+
+        @Override
+        public void visitParens(JCParens tree) {
+            printTree("expr", tree.expr);
+        }
+
+        @Override
+        public void visitAssign(JCAssign tree) {
+            printTree("lhs", tree.lhs);
+            printTree("rhs", tree.rhs);
+        }
+
+        @Override
+        public void visitAssignop(JCAssignOp tree) {
+            printTree("lhs", tree.lhs);
+            printTree("rhs", tree.rhs);
+        }
+
+        @Override
+        public void visitUnary(JCUnary tree) {
+            printTree("arg", tree.arg);
+        }
+
+        @Override
+        public void visitBinary(JCBinary tree) {
+            printTree("lhs", tree.lhs);
+            printTree("rhs", tree.rhs);
+        }
+
+        @Override
+        public void visitTypeCast(JCTypeCast tree) {
+            printTree("clazz", tree.clazz);
+            printTree("expr", tree.expr);
+        }
+
+        @Override
+        public void visitTypeTest(JCInstanceOf tree) {
+            printTree("expr", tree.expr);
+            printTree("clazz", tree.clazz);
+        }
+