changeset 1809:c2e11e2ec4a3 jdk8-b75

Merge
author lana
date Sat, 26 Jan 2013 19:24:46 -0800
parents 54e4ba223319 09f65aad4759
children 716935fec613 2d6789a725a4 b7cb3d7ade25
files test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java test/tools/javac/diags/examples/ContainedByInheritedMismatch.java test/tools/javac/diags/examples/ContainedByNoValue.java test/tools/javac/diags/examples/ContainedByNonDefault.java test/tools/javac/diags/examples/ContainedByRetentionMismatch.java test/tools/javac/diags/examples/ContainedByTargetMismatch.java test/tools/javac/diags/examples/ContainedByWrongValueType.java test/tools/javac/diags/examples/InferredDoNotConformToLower.java test/tools/javac/diags/examples/NoUniqueMaximalInstance.java test/tools/javac/diags/examples/WrongContainedBy.java test/tools/javac/diags/examples/WrongContainerFor.java test/tools/javac/lambda/MethodReference26.out test/tools/javac/lambda/TargetType06.out test/tools/javac/lambda/TargetType11.out test/tools/javac/lambda/TargetType45.out test/tools/javac/lambda/VoidCompatibility.out test/tools/javac/typeAnnotations/newlocations/BasicTest.java test/tools/javac/typeAnnotations/newlocations/BasicTest.out
diffstat 629 files changed, 30453 insertions(+), 2773 deletions(-) [+]
line wrap: on
line diff
--- a/make/build.properties	Thu Jan 24 16:49:37 2013 -0800
+++ b/make/build.properties	Sat Jan 26 19:24:46 2013 -0800
@@ -29,18 +29,18 @@
 # Override this path as needed, either on the command line or in
 # one of the standard user build.properties files (see build.xml)
 
-# boot.java.home = /opt/jdk/1.6.0
+# boot.java.home = /opt/jdk/1.7.0
 boot.java = ${boot.java.home}/bin/java
 boot.javac = ${boot.java.home}/bin/javac
-boot.javac.source = 6
-boot.javac.target = 6
+boot.javac.source = 7
+boot.javac.target = 7
 
 # This is the JDK used to run the product version of the tools,
 # for example, for testing. If you're building a complete JDK, specify that.
 # Override this path as needed, either on the command line or in
 # one of the standard user build.properties files (see build.xml)
 
-# target.java.home = /opt/jdk/1.7.0
+# target.java.home = /opt/jdk/1.8.0
 target.java = ${target.java.home}/bin/java
 
 # Version info -- override as needed
@@ -161,6 +161,14 @@
 
 #
 
+sjavac.includes = \
+        com/sun/tools/sjavac/ 
+
+sjavac.tests = \
+        tools/sjavac
+        
+#
+
 # The following files require the latest JDK to be available.
 # The API can be provided by using a suitable boot.java.home
 # or by setting import.jdk
--- a/make/build.xml	Thu Jan 24 16:49:37 2013 -0800
+++ b/make/build.xml	Sat Jan 26 19:24:46 2013 -0800
@@ -241,15 +241,15 @@
     </target>
 
     <target name="build-bootstrap-tools"
-        depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah"
+        depends="build-bootstrap-javac,build-bootstrap-javadoc,build-bootstrap-doclets,build-bootstrap-javah,build-bootstrap-sjavac"
     />
 
     <target name="build-all-tools"
-        depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap"
+        depends="build-javac,build-javadoc,build-doclets,build-javah,build-javap,build-sjavac"
     />
 
     <target name="build-all-classes" depends="build-bootstrap-javac,-create-import-jdk-stubs">
-        <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes}"/>
+        <build-classes includes="${javac.includes} ${javadoc.includes} ${doclets.includes} ${javah.includes} ${javap.includes} ${sjavac.includes}"/>
     </target>
 
     <!-- clean -->
@@ -656,6 +656,40 @@
 
     <target name="javap" depends="build-javap,jtreg-javap,findbugs-javap"/>
 
+    <!--
+    **** sjavac targets.
+    -->
+
+    <target name="build-bootstrap-sjavac"
+            depends="-def-build-bootstrap-classes,-def-build-bootstrap-jar,-def-build-bootstrap-tool">
+        <build-bootstrap-classes includes="${sjavac.includes}"/>
+        <build-bootstrap-jar     name="sjavac" includes="${sjavac.includes}"
+                                 jarmainclass="com.sun.tools.sjavac.Main"/>
+        <build-bootstrap-tool    name="sjavac"/>
+    </target>
+
+    <target name="build-classes-sjavac" depends="build-classes-javac">
+        <build-classes includes="${sjavac.includes}"/>
+    </target>
+
+    <target name="build-sjavac" depends="build-classes-sjavac">
+        <build-jar  name="sjavac" includes="${sjavac.includes}"
+                    jarmainclass="com.sun.tools.sjavac.Main"
+                    jarclasspath="sjavac.jar"/>
+        <build-tool name="sjavac"/>
+    </target>
+    
+    <!-- (no javadoc for javap) -->
+
+    <target name="jtreg-sjavac" depends="build-sjavac,-def-jtreg">
+        <jtreg-tool name="sjavac" tests="${sjavac.tests}"/>
+    </target>
+
+    <target name="findbugs-sjavac" depends="build-sjavac,-def-findbugs">
+        <findbugs-tool name="sjavac"/>
+    </target>
+
+    <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
 
     <!--
     **** Create import JDK stubs.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/javadoc/AnnotatedType.java	Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.javadoc;
+
+
+/**
+ * Represents an annotated type.
+ * For example:
+ * <pre>
+ *      {@code @NonNull String}
+ *      {@code @Positive int}
+ * </pre>
+ *
+ * @author Mahmood Ali
+ * @since 1.8
+ */
+public interface AnnotatedType extends Type {
+
+    AnnotationDesc[] annotations();
+
+    Type underlyingType();
+}
--- a/src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/javadoc/ExecutableMemberDoc.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -88,6 +88,15 @@
     Parameter[] parameters();
 
     /**
+     * Get the receiver annotations of this executable element.
+     * Return an empty array if there are none.
+     *
+     * @return the receiver annotations of this executable element.
+     * @since 1.8
+     */
+    AnnotationDesc[] receiverAnnotations();
+
+    /**
      * Return the throws tags in this method.
      *
      * @return an array of ThrowTag containing all <code>&#64;exception</code>
--- a/src/share/classes/com/sun/javadoc/Type.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/javadoc/Type.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -142,6 +142,16 @@
     WildcardType asWildcardType();
 
     /**
+     * Returns this type as a <code>AnnotatedType</code> if it represents
+     * an annotated type.
+     *
+     * @return a <code>AnnotatedType</code> if the type if an annotated type,
+     *         or null if it is not
+     * @since 1.8
+     */
+    AnnotatedType asAnnotatedType();
+
+    /**
      * Return this type as an <code>AnnotationTypeDoc</code> if it represents
      * an annotation type.  Array dimensions are ignored.
      *
--- a/src/share/classes/com/sun/javadoc/TypeVariable.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/javadoc/TypeVariable.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,4 +55,11 @@
      *         which this type variable is declared.
      */
     ProgramElementDoc owner();
+
+    /**
+     * Get the annotations of this program element.
+     * Return an empty array if there are none.
+     */
+    public AnnotationDesc[] annotations();
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/source/tree/AnnotatedTypeTree.java	Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2008, 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.source.tree;
+
+import java.util.List;
+
+/**
+ * A tree node for an annotated type
+ *
+ * For example:
+ * <pre>
+ *    {@code @}<em>annotationType String</em>
+ *    {@code @}<em>annotationType</em> ( <em>arguments</em> ) <em>Date</em>
+ * </pre>
+ *
+ * @see "JSR 308: Annotations on Java Types"
+ *
+ * @author Mahmood Ali
+ * @since 1.8
+ */
+public interface AnnotatedTypeTree extends ExpressionTree {
+    List<? extends AnnotationTree> getAnnotations();
+    ExpressionTree getUnderlyingType();
+}
--- a/src/share/classes/com/sun/source/tree/MethodTree.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/source/tree/MethodTree.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -52,6 +52,7 @@
     Tree getReturnType();
     List<? extends TypeParameterTree> getTypeParameters();
     List<? extends VariableTree> getParameters();
+    VariableTree getReceiverParameter();
     List<? extends ExpressionTree> getThrows();
     BlockTree getBody();
     Tree getDefaultValue(); // for annotation types
--- a/src/share/classes/com/sun/source/tree/Tree.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/source/tree/Tree.java	Sat Jan 26 19:24:46 2013 -0800
@@ -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
@@ -46,12 +46,21 @@
      */
     public enum Kind {
 
+        ANNOTATED_TYPE(AnnotatedTypeTree.class),
+
         /**
-         * Used for instances of {@link AnnotationTree}.
+         * Used for instances of {@link AnnotationTree}
+         * representing declaration annotations.
          */
         ANNOTATION(AnnotationTree.class),
 
         /**
+         * Used for instances of {@link AnnotationTree}
+         * representing type annotations.
+         */
+        TYPE_ANNOTATION(AnnotationTree.class),
+
+        /**
          * Used for instances of {@link ArrayAccessTree}.
          */
         ARRAY_ACCESS(ArrayAccessTree.class),
--- a/src/share/classes/com/sun/source/tree/TreeVisitor.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/source/tree/TreeVisitor.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -57,6 +57,7 @@
  * @since 1.6
  */
 public interface TreeVisitor<R,P> {
+    R visitAnnotatedType(AnnotatedTypeTree node, P p);
     R visitAnnotation(AnnotationTree node, P p);
     R visitMethodInvocation(MethodInvocationTree node, P p);
     R visitAssert(AssertTree node, P p);
--- a/src/share/classes/com/sun/source/tree/TypeParameterTree.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/source/tree/TypeParameterTree.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -47,4 +47,5 @@
 public interface TypeParameterTree extends Tree {
     Name getName();
     List<? extends Tree> getBounds();
+    List<? extends AnnotationTree> getAnnotations();
 }
--- a/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, 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
@@ -260,6 +260,10 @@
         return defaultAction(node, p);
     }
 
+    public R visitAnnotatedType(AnnotatedTypeTree node, P p) {
+        return defaultAction(node, p);
+    }
+
     public R visitErroneous(ErroneousTree node, P p) {
         return defaultAction(node, p);
     }
--- a/src/share/classes/com/sun/source/util/TaskEvent.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/source/util/TaskEvent.java	Sat Jan 26 19:24:46 2013 -0800
@@ -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
@@ -60,7 +60,7 @@
          **/
         GENERATE,
         /**
-         * For events relating to overall annotaion processing.
+         * For events relating to overall annotation processing.
          **/
         ANNOTATION_PROCESSING,
         /**
--- a/src/share/classes/com/sun/source/util/TreeScanner.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/source/util/TreeScanner.java	Sat Jan 26 19:24:46 2013 -0800
@@ -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
@@ -138,6 +138,7 @@
         r = scanAndReduce(node.getReturnType(), p, r);
         r = scanAndReduce(node.getTypeParameters(), p, r);
         r = scanAndReduce(node.getParameters(), p, r);
+        r = scanAndReduce(node.getReceiverParameter(), p, r);
         r = scanAndReduce(node.getThrows(), p, r);
         r = scanAndReduce(node.getBody(), p, r);
         r = scanAndReduce(node.getDefaultValue(), p, r);
@@ -376,7 +377,8 @@
     }
 
     public R visitTypeParameter(TypeParameterTree node, P p) {
-        R r = scan(node.getBounds(), p);
+        R r = scan(node.getAnnotations(), p);
+        r = scanAndReduce(node.getBounds(), p, r);
         return r;
     }
 
@@ -394,6 +396,12 @@
         return r;
     }
 
+   public R visitAnnotatedType(AnnotatedTypeTree node, P p) {
+       R r = scan(node.getAnnotations(), p);
+       r = scanAndReduce(node.getUnderlyingType(), p, r);
+       return r;
+   }
+
     public R visitOther(Tree node, P p) {
         return null;
     }
--- a/src/share/classes/com/sun/tools/classfile/Attribute.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/classfile/Attribute.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,8 @@
     public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
     public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
     public static final String RuntimeInvisibleParameterAnnotations = "RuntimeInvisibleParameterAnnotations";
+    public static final String RuntimeVisibleTypeAnnotations = "RuntimeVisibleTypeAnnotations";
+    public static final String RuntimeInvisibleTypeAnnotations = "RuntimeInvisibleTypeAnnotations";
     public static final String Signature                = "Signature";
     public static final String SourceDebugExtension     = "SourceDebugExtension";
     public static final String SourceFile               = "SourceFile";
@@ -120,6 +122,8 @@
                 standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
                 standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class);
                 standardAttributes.put(RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations_attribute.class);
+                standardAttributes.put(RuntimeVisibleTypeAnnotations, RuntimeVisibleTypeAnnotations_attribute.class);
+                standardAttributes.put(RuntimeInvisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations_attribute.class);
                 standardAttributes.put(Signature,     Signature_attribute.class);
                 standardAttributes.put(SourceID, SourceID_attribute.class);
             }
@@ -178,6 +182,8 @@
         R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
         R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
         R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p);
+        R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p);
+        R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p);
         R visitSignature(Signature_attribute attr, P p);
         R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p);
         R visitSourceFile(SourceFile_attribute attr, P p);
--- a/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,6 +1,6 @@
 
 /*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -498,6 +498,16 @@
             return null;
         }
 
+        public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
+            annotationWriter.write(attr.annotations, out);
+            return null;
+        }
+
+        public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
+            annotationWriter.write(attr.annotations, out);
+            return null;
+        }
+
         public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
             out.writeByte(attr.parameter_annotations.length);
             for (Annotation[] annos: attr.parameter_annotations)
@@ -657,6 +667,12 @@
                 write(anno, out);
         }
 
+        public void write(TypeAnnotation[] annos, ClassOutputStream out) {
+            out.writeShort(annos.length);
+            for (TypeAnnotation anno: annos)
+                write(anno, out);
+        }
+
         public void write(Annotation anno, ClassOutputStream out) {
             out.writeShort(anno.type_index);
             out.writeShort(anno.element_value_pairs.length);
@@ -664,6 +680,11 @@
                 write(p, out);
         }
 
+        public void write(TypeAnnotation anno, ClassOutputStream out) {
+            write(anno.position, out);
+            write(anno.annotation, out);
+        }
+
         public void write(element_value_pair pair, ClassOutputStream out) {
             out.writeShort(pair.element_name_index);
             write(pair.value, out);
@@ -702,5 +723,89 @@
             return null;
         }
 
+        // TODO: Move this to TypeAnnotation to be closer with similar logic?
+        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:
+                out.writeShort(p.offset);
+                break;
+            // local variable
+            case LOCAL_VARIABLE:
+            // resource variable
+            case RESOURCE_VARIABLE:
+                int table_length = p.lvarOffset.length;
+                out.writeShort(table_length);
+                for (int i = 0; i < table_length; ++i) {
+                    out.writeShort(1);  // for table length
+                    out.writeShort(p.lvarOffset[i]);
+                    out.writeShort(p.lvarLength[i]);
+                    out.writeShort(p.lvarIndex[i]);
+                }
+                break;
+            // exception parameter
+            case EXCEPTION_PARAMETER:
+                out.writeByte(p.exception_index);
+                break;
+            // method receiver
+            case METHOD_RECEIVER:
+                // Do nothing
+                break;
+            // type parameters
+            case CLASS_TYPE_PARAMETER:
+            case METHOD_TYPE_PARAMETER:
+                out.writeByte(p.parameter_index);
+                break;
+            // type parameters bounds
+            case CLASS_TYPE_PARAMETER_BOUND:
+            case METHOD_TYPE_PARAMETER_BOUND:
+                out.writeByte(p.parameter_index);
+                out.writeByte(p.bound_index);
+                break;
+            // class extends or implements clause
+            case CLASS_EXTENDS:
+                out.writeByte(p.type_index);
+                break;
+            // throws
+            case THROWS:
+                out.writeByte(p.type_index);
+                break;
+            // method parameter
+            case METHOD_FORMAL_PARAMETER:
+                out.writeByte(p.parameter_index);
+                break;
+            // method/constructor/reference type argument
+            case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+            case METHOD_INVOCATION_TYPE_ARGUMENT:
+            case METHOD_REFERENCE_TYPE_ARGUMENT:
+                out.writeShort(p.offset);
+                out.writeByte(p.type_index);
+                break;
+            // We don't need to worry about these
+            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:
+                throw new AssertionError("ClassWriter: Unknown target type for position: " + p);
+            }
+
+            { // Append location data for generics/arrays.
+                // TODO: check for overrun?
+                out.writeByte((byte)p.location.size());
+                for (int i : TypeAnnotation.Position.getBinaryFromTypePath(p.location))
+                    out.writeByte((byte)i);
+            }
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/RuntimeInvisibleTypeAnnotations_attribute.java	Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See JSR 308 specification, Section 3.
+ *
+ *  <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 RuntimeInvisibleTypeAnnotations_attribute extends RuntimeTypeAnnotations_attribute {
+    RuntimeInvisibleTypeAnnotations_attribute(ClassReader cr, int name_index, int length)
+            throws IOException, Annotation.InvalidAnnotation {
+        super(cr, name_index, length);
+    }
+
+    public RuntimeInvisibleTypeAnnotations_attribute(ConstantPool cp, TypeAnnotation[] annotations)
+            throws ConstantPoolException {
+        this(cp.getUTF8Index(Attribute.RuntimeInvisibleTypeAnnotations), annotations);
+    }
+
+    public RuntimeInvisibleTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) {
+        super(name_index, annotations);
+    }
+
+    public <R, P> R accept(Visitor<R, P> visitor, P p) {
+        return visitor.visitRuntimeInvisibleTypeAnnotations(this, p);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/RuntimeTypeAnnotations_attribute.java	Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,61 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See JSR 308 specification, Section 3.
+ *
+ *  <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 abstract class RuntimeTypeAnnotations_attribute extends Attribute {
+    protected RuntimeTypeAnnotations_attribute(ClassReader cr, int name_index, int length)
+            throws IOException, Annotation.InvalidAnnotation {
+        super(name_index, length);
+        int num_annotations = cr.readUnsignedShort();
+        annotations = new TypeAnnotation[num_annotations];
+        for (int i = 0; i < annotations.length; i++)
+            annotations[i] = new TypeAnnotation(cr);
+    }
+
+    protected RuntimeTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) {
+        super(name_index, length(annotations));
+        this.annotations = annotations;
+    }
+
+    private static int length(TypeAnnotation[] annos) {
+        int n = 2;
+        for (TypeAnnotation anno: annos)
+            n += anno.length();
+        return n;
+    }
+
+    public final TypeAnnotation[] annotations;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/RuntimeVisibleTypeAnnotations_attribute.java	Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See JSR 308 specification, Section 3.
+ *
+ *  <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 RuntimeVisibleTypeAnnotations_attribute extends RuntimeTypeAnnotations_attribute {
+    RuntimeVisibleTypeAnnotations_attribute(ClassReader cr, int name_index, int length)
+            throws IOException, Annotation.InvalidAnnotation {
+        super(cr, name_index, length);
+    }
+
+    public RuntimeVisibleTypeAnnotations_attribute(ConstantPool cp, TypeAnnotation[] annotations)
+            throws ConstantPoolException {
+        this(cp.getUTF8Index(Attribute.RuntimeVisibleTypeAnnotations), annotations);
+    }
+
+    public RuntimeVisibleTypeAnnotations_attribute(int name_index, TypeAnnotation[] annotations) {
+        super(name_index, annotations);
+    }
+
+    public <R, P> R accept(Visitor<R, P> visitor, P p) {
+        return visitor.visitRuntimeVisibleTypeAnnotations(this, p);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/TypeAnnotation.java	Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,656 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.sun.tools.classfile.TypeAnnotation.Position.TypePathEntry;
+
+/**
+ * See JSR 308 specification, Section 3.
+ *
+ *  <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 TypeAnnotation {
+    TypeAnnotation(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
+        constant_pool = cr.getConstantPool();
+        position = read_position(cr);
+        annotation = new Annotation(cr);
+    }
+
+    public TypeAnnotation(ConstantPool constant_pool,
+            Annotation annotation, Position position) {
+        this.constant_pool = constant_pool;
+        this.position = position;
+        this.annotation = annotation;
+    }
+
+    public int length() {
+        int n = annotation.length();
+        n += position_length(position);
+        return n;
+    }
+
+    @Override
+    public String toString() {
+        try {
+            return "@" + constant_pool.getUTF8Value(annotation.type_index).toString().substring(1) +
+                    " pos: " + position.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return e.toString();
+        }
+    }
+
+    public final ConstantPool constant_pool;
+    public final Position position;
+    public final Annotation annotation;
+
+    private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
+        // Copied from ClassReader
+        int tag = cr.readUnsignedByte(); // TargetType tag is a byte
+        if (!TargetType.isValidTargetTypeValue(tag))
+            throw new Annotation.InvalidAnnotation("TypeAnnotation: Invalid type annotation target type value: " + String.format("0x%02X", tag));
+
+        TargetType type = TargetType.fromTargetTypeValue(tag);
+
+        Position position = new Position();
+        position.type = type;
+
+        switch (type) {
+        // type cast
+        case CAST:
+        // instanceof
+        case INSTANCEOF:
+        // new expression
+        case NEW:
+            position.offset = cr.readUnsignedShort();
+            break;
+        // local variable
+        case LOCAL_VARIABLE:
+        // resource variable
+        case RESOURCE_VARIABLE:
+            int table_length = cr.readUnsignedShort();
+            position.lvarOffset = new int[table_length];
+            position.lvarLength = new int[table_length];
+            position.lvarIndex = new int[table_length];
+            for (int i = 0; i < table_length; ++i) {
+                position.lvarOffset[i] = cr.readUnsignedShort();
+                position.lvarLength[i] = cr.readUnsignedShort();
+                position.lvarIndex[i] = cr.readUnsignedShort();
+            }
+            break;
+        // exception parameter
+        case EXCEPTION_PARAMETER:
+            position.exception_index = cr.readUnsignedByte();
+            break;
+        // method receiver
+        case METHOD_RECEIVER:
+            // Do nothing
+            break;
+        // type parameter
+        case CLASS_TYPE_PARAMETER:
+        case METHOD_TYPE_PARAMETER:
+            position.parameter_index = cr.readUnsignedByte();
+            break;
+        // type parameter bound
+        case CLASS_TYPE_PARAMETER_BOUND:
+        case METHOD_TYPE_PARAMETER_BOUND:
+            position.parameter_index = cr.readUnsignedByte();
+            position.bound_index = cr.readUnsignedByte();
+            break;
+        // class extends or implements clause
+        case CLASS_EXTENDS:
+            int in = cr.readUnsignedShort();
+            if (in == 0xFFFF)
+                in = -1;
+            position.type_index = in;
+            break;
+        // throws
+        case THROWS:
+            position.type_index = cr.readUnsignedShort();
+            break;
+        // method parameter
+        case METHOD_FORMAL_PARAMETER:
+            position.parameter_index = cr.readUnsignedByte();
+            break;
+        // method/constructor/reference type argument
+        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+        case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case METHOD_REFERENCE_TYPE_ARGUMENT:
+            position.offset = cr.readUnsignedShort();
+            position.type_index = cr.readUnsignedByte();
+            break;
+        // We don't need to worry about these
+        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:
+            throw new AssertionError("TypeAnnotation: Unknown target type: " + type);
+        }
+
+        { // Write type path
+            int len = cr.readUnsignedByte();
+            List<Integer> loc = new ArrayList<Integer>(len);
+            for (int i = 0; i < len * TypePathEntry.bytesPerEntry; ++i)
+                loc.add(cr.readUnsignedByte());
+            position.location = Position.getTypePathFromBinary(loc);
+        }
+        return position;
+    }
+
+    private static int position_length(Position pos) {
+        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;
+            break;
+        // local variable
+        case LOCAL_VARIABLE:
+        // resource variable
+        case RESOURCE_VARIABLE:
+            n += 2; // table_length;
+            int table_length = pos.lvarOffset.length;
+            n += 2 * table_length; // offset
+            n += 2 * table_length; // length;
+            n += 2 * table_length; // index
+            break;
+        // exception parameter
+        case EXCEPTION_PARAMETER:
+            n += 1; // exception_index
+            break;
+        // method receiver
+        case METHOD_RECEIVER:
+            // Do nothing
+            break;
+        // type parameter
+        case CLASS_TYPE_PARAMETER:
+        case METHOD_TYPE_PARAMETER:
+            n += 1; // parameter_index;
+            break;
+        // type parameter bound
+        case CLASS_TYPE_PARAMETER_BOUND:
+        case METHOD_TYPE_PARAMETER_BOUND:
+            n += 1; // parameter_index
+            n += 1; // bound_index
+            break;
+        // class extends or implements clause
+        case CLASS_EXTENDS:
+            n += 2; // type_index
+            break;
+        // throws
+        case THROWS:
+            n += 2; // type_index
+            break;
+        // method parameter
+        case METHOD_FORMAL_PARAMETER:
+            n += 1; // parameter_index
+            break;
+        // method/constructor/reference type argument
+        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+        case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case METHOD_REFERENCE_TYPE_ARGUMENT:
+            n += 2; // offset
+            n += 1; // type index
+            break;
+        // We don't need to worry about these
+        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:
+            throw new AssertionError("TypeAnnotation: Unknown target type: " + pos.type);
+        }
+
+        {
+            n += 1; // length
+            n += TypePathEntry.bytesPerEntry * pos.location.size(); // bytes for actual array
+        }
+
+        return n;
+    }
+
+    // Code duplicated from com.sun.tools.javac.code.TypeAnnotationPosition
+    public static class Position {
+        public enum TypePathEntryKind {
+            ARRAY(0),
+            INNER_TYPE(1),
+            WILDCARD(2),
+            TYPE_ARGUMENT(3);
+
+            public final int tag;
+
+            private TypePathEntryKind(int tag) {
+                this.tag = tag;
+            }
+        }
+
+        public static class TypePathEntry {
+            /** The fixed number of bytes per TypePathEntry. */
+            public static final int bytesPerEntry = 2;
+
+            public final TypePathEntryKind tag;
+            public final int arg;
+
+            public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
+            public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
+            public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
+
+            private TypePathEntry(TypePathEntryKind tag) {
+                if (!(tag == TypePathEntryKind.ARRAY ||
+                        tag == TypePathEntryKind.INNER_TYPE ||
+                        tag == TypePathEntryKind.WILDCARD)) {
+                    throw new AssertionError("Invalid TypePathEntryKind: " + tag);
+                }
+                this.tag = tag;
+                this.arg = 0;
+            }
+
+            public TypePathEntry(TypePathEntryKind tag, int arg) {
+                if (tag != TypePathEntryKind.TYPE_ARGUMENT) {
+                    throw new AssertionError("Invalid TypePathEntryKind: " + tag);
+                }
+                this.tag = tag;
+                this.arg = arg;
+            }
+
+            public static TypePathEntry fromBinary(int tag, int arg) {
+                if (arg != 0 && tag != TypePathEntryKind.TYPE_ARGUMENT.tag) {
+                    throw new AssertionError("Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
+                }
+                switch (tag) {
+                case 0:
+                    return ARRAY;
+                case 1:
+                    return INNER_TYPE;
+                case 2:
+                    return WILDCARD;
+                case 3:
+                    return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
+                default:
+                    throw new AssertionError("Invalid TypePathEntryKind tag: " + tag);
+                }
+            }
+
+            @Override
+            public String toString() {
+                return tag.toString() +
+                        (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
+            }
+
+            @Override
+            public boolean equals(Object other) {
+                if (! (other instanceof TypePathEntry)) {
+                    return false;
+                }
+                TypePathEntry tpe = (TypePathEntry) other;
+                return this.tag == tpe.tag && this.arg == tpe.arg;
+            }
+
+            @Override
+            public int hashCode() {
+                return this.tag.hashCode() * 17 + this.arg;
+            }
+        }
+
+        public TargetType type = TargetType.UNKNOWN;
+
+        // For generic/array types.
+        // TODO: or should we use null? Noone will use this object.
+        public List<TypePathEntry> location = new ArrayList<TypePathEntry>(0);
+
+        // Tree position.
+        public int pos = -1;
+
+        // For typecasts, type tests, new (and locals, as start_pc).
+        public boolean isValidOffset = false;
+        public int offset = -1;
+
+        // For locals. arrays same length
+        public int[] lvarOffset = null;
+        public int[] lvarLength = null;
+        public int[] lvarIndex = null;
+
+        // For type parameter bound
+        public int bound_index = Integer.MIN_VALUE;
+
+        // For type parameter and method parameter
+        public int parameter_index = Integer.MIN_VALUE;
+
+        // For class extends, implements, and throws clauses
+        public int type_index = Integer.MIN_VALUE;
+
+        // For exception parameters, index into exception table
+        public int exception_index = Integer.MIN_VALUE;
+
+        public Position() {}
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append('[');
+            sb.append(type);
+
+            switch (type) {
+            // type cast
+            case CAST:
+            // instanceof
+            case INSTANCEOF:
+            // new expression
+            case NEW:
+                sb.append(", offset = ");
+                sb.append(offset);
+                break;
+            // local variable
+            case LOCAL_VARIABLE:
+            // resource variable
+            case RESOURCE_VARIABLE:
+                if (lvarOffset == null) {
+                    sb.append(", lvarOffset is null!");
+                    break;
+                }
+                sb.append(", {");
+                for (int i = 0; i < lvarOffset.length; ++i) {
+                    if (i != 0) sb.append("; ");
+                    sb.append("start_pc = ");
+                    sb.append(lvarOffset[i]);
+                    sb.append(", length = ");
+                    sb.append(lvarLength[i]);
+                    sb.append(", index = ");
+                    sb.append(lvarIndex[i]);
+                }
+                sb.append("}");
+                break;
+            // method receiver
+            case METHOD_RECEIVER:
+                // Do nothing
+                break;
+            // type parameter
+            case CLASS_TYPE_PARAMETER:
+            case METHOD_TYPE_PARAMETER:
+                sb.append(", param_index = ");
+                sb.append(parameter_index);
+                break;
+            // type parameter bound
+            case CLASS_TYPE_PARAMETER_BOUND:
+            case METHOD_TYPE_PARAMETER_BOUND:
+                sb.append(", param_index = ");
+                sb.append(parameter_index);
+                sb.append(", bound_index = ");
+                sb.append(bound_index);
+                break;
+            // class extends or implements clause
+            case CLASS_EXTENDS:
+                sb.append(", type_index = ");
+                sb.append(type_index);
+                break;
+            // throws
+            case THROWS:
+                sb.append(", type_index = ");
+                sb.append(type_index);
+                break;
+            // exception parameter
+            case EXCEPTION_PARAMETER:
+                sb.append(", exception_index = ");
+                sb.append(exception_index);
+                break;
+            // method parameter
+            case METHOD_FORMAL_PARAMETER:
+                sb.append(", param_index = ");
+                sb.append(parameter_index);
+                break;
+            // method/constructor/reference type argument
+            case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+            case METHOD_INVOCATION_TYPE_ARGUMENT:
+            case METHOD_REFERENCE_TYPE_ARGUMENT:
+                sb.append(", offset = ");
+                sb.append(offset);
+                sb.append(", type_index = ");
+                sb.append(type_index);
+                break;
+            // We don't need to worry about these
+            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;
+            default:
+                throw new AssertionError("Unknown target type: " + type);
+            }
+
+            // Append location data for generics/arrays.
+            if (!location.isEmpty()) {
+                sb.append(", location = (");
+                sb.append(location);
+                sb.append(")");
+            }
+
+            sb.append(", pos = ");
+            sb.append(pos);
+
+            sb.append(']');
+            return sb.toString();
+        }
+
+        /**
+         * Indicates whether the target tree of the annotation has been optimized
+         * away from classfile or not.
+         * @return true if the target has not been optimized away
+         */
+        public boolean emitToClassfile() {
+            return !type.isLocal() || isValidOffset;
+        }
+
+        /**
+         * Decode the binary representation for a type path and set
+         * the {@code location} field.
+         *
+         * @param list The bytecode representation of the type path.
+         */
+        public static List<TypePathEntry> getTypePathFromBinary(List<Integer> list) {
+            List<TypePathEntry> loc = new ArrayList<TypePathEntry>(list.size() / TypePathEntry.bytesPerEntry);
+            int idx = 0;
+            while (idx < list.size()) {
+                if (idx + 1 == list.size()) {
+                    throw new AssertionError("Could not decode type path: " + list);
+                }
+                loc.add(TypePathEntry.fromBinary(list.get(idx), list.get(idx + 1)));
+                idx += 2;
+            }
+            return loc;
+        }
+
+        public static List<Integer> getBinaryFromTypePath(List<TypePathEntry> locs) {
+            List<Integer> loc = new ArrayList<Integer>(locs.size() * TypePathEntry.bytesPerEntry);
+            for (TypePathEntry tpe : locs) {
+                loc.add(tpe.tag.tag);
+                loc.add(tpe.arg);
+            }
+            return loc;
+        }
+    }
+
+    // Code duplicated from com.sun.tools.javac.code.TargetType
+    // The IsLocal flag could be removed here.
+    public enum TargetType {
+        /** For annotations on a class type parameter declaration. */
+        CLASS_TYPE_PARAMETER(0x00),
+
+        /** For annotations on a method type parameter declaration. */
+        METHOD_TYPE_PARAMETER(0x01),
+
+        /** For annotations on the type of an "extends" or "implements" clause. */
+        CLASS_EXTENDS(0x10),
+
+        /** For annotations on a bound of a type parameter of a class. */
+        CLASS_TYPE_PARAMETER_BOUND(0x11),
+
+        /** For annotations on a bound of a type parameter of a method. */
+        METHOD_TYPE_PARAMETER_BOUND(0x12),
+
+        /** For annotations on a field. */
+        FIELD(0x13),
+
+        /** For annotations on a method return type. */
+        METHOD_RETURN(0x14),
+
+        /** For annotations on the method receiver. */
+        METHOD_RECEIVER(0x15),
+
+        /** For annotations on a method parameter. */
+        METHOD_FORMAL_PARAMETER(0x16),
+
+        /** For annotations on a throws clause in a method declaration. */
+        THROWS(0x17),
+
+        /** For annotations on a local variable. */
+        LOCAL_VARIABLE(0x40, true),
+
+        /** For annotations on a resource variable. */
+        RESOURCE_VARIABLE(0x41, true),
+
+        /** 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),
+
+        /** For annotations on an object creation expression. */
+        NEW(0x45, true),
+
+        /** For annotations on a type argument of an object creation expression. */
+        CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
+
+        /** For annotations on a type argument of a method call. */
+        METHOD_INVOCATION_TYPE_ARGUMENT(0x47, 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 method reference. */
+        METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
+
+        /** For annotations with an unknown target. */
+        UNKNOWN(0xFF);
+
+        private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x50;
+
+        private final int targetTypeValue;
+        private final boolean isLocal;
+
+        private TargetType(int targetTypeValue) {
+            this(targetTypeValue, false);
+        }
+
+        private TargetType(int targetTypeValue, boolean isLocal) {
+            if (targetTypeValue < 0
+                    || targetTypeValue > 255)
+                    throw new AssertionError("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue));
+            this.targetTypeValue = targetTypeValue;
+            this.isLocal = isLocal;
+        }
+
+        /**
+         * Returns whether or not this TargetType represents an annotation whose
+         * target is exclusively a tree in a method body
+         *
+         * Note: wildcard bound targets could target a local tree and a class
+         * member declaration signature tree
+         */
+        public boolean isLocal() {
+            return isLocal;
+        }
+
+        public int targetTypeValue() {
+            return this.targetTypeValue;
+        }
+
+        private static final TargetType[] targets;
+
+        static {
+            targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
+            TargetType[] alltargets = values();
+            for (TargetType target : alltargets) {
+                if (target.targetTypeValue != UNKNOWN.targetTypeValue)
+                    targets[target.targetTypeValue] = target;
+            }
+            for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) {
+                if (targets[i] == null)
+                    targets[i] = UNKNOWN;
+            }
+        }
+
+        public static boolean isValidTargetTypeValue(int tag) {
+            if (tag == UNKNOWN.targetTypeValue)
+                return true;
+            return (tag >= 0 && tag < targets.length);
+        }
+
+        public static TargetType fromTargetTypeValue(int tag) {
+            if (tag == UNKNOWN.targetTypeValue)
+                return UNKNOWN;
+
+            if (tag < 0 || tag >= targets.length)
+                throw new AssertionError("Unknown TargetType: " + tag);
+            return targets[tag];
+        }
+    }
+}
--- a/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/AbstractExecutableMemberWriter.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -139,6 +139,15 @@
         }
     }
 
+    protected void addReceiverAnnotations(ExecutableMemberDoc member,
+            Content tree) {
+        if (member.receiverAnnotations().length > 0) {
+            tree.addContent(writer.getSpace());
+            writer.addReceiverAnnotationInfo(member, tree);
+        }
+    }
+
+
     /**
      * Add all the parameters for the executable member.
      *
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,10 @@
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
+import com.sun.tools.doclint.DocLint;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javadoc.RootDocImpl;
 
 /**
  * Configure the output based on the command line options.
@@ -172,6 +174,11 @@
     public boolean createoverview = false;
 
     /**
+     * Collected set of doclint options
+     */
+    public Set<String> doclintOpts = new LinkedHashSet<String>();
+
+    /**
      * Unique Resource Handler for this package.
      */
     public final MessageRetriever standardmessage;
@@ -255,6 +262,10 @@
                 nooverview = true;
             } else if (opt.equals("-overview")) {
                 overview = true;
+            } else if (opt.equals("-xdoclint")) {
+                doclintOpts.add(null);
+            } else if (opt.startsWith("-xdoclint:")) {
+                doclintOpts.add(opt.substring(opt.indexOf(":") + 1));
             }
         }
         if (root.specifiedClasses().length > 0) {
@@ -270,6 +281,10 @@
         }
         setCreateOverview();
         setTopFile(root);
+
+        if (root instanceof RootDocImpl) {
+            ((RootDocImpl) root).initDocLint(doclintOpts);
+        }
     }
 
     /**
@@ -303,7 +318,9 @@
             option.equals("-serialwarn") ||
             option.equals("-use") ||
             option.equals("-nonavbar") ||
-            option.equals("-nooverview")) {
+            option.equals("-nooverview") ||
+            option.equals("-xdoclint") ||
+            option.startsWith("-xdoclint:")) {
             return 1;
         } else if (option.equals("-help")) {
             System.out.println(getText("doclet.usage"));
@@ -410,6 +427,16 @@
                     return false;
                 }
                 noindex = true;
+            } else if (opt.startsWith("-xdoclint:")) {
+                if (opt.contains("/")) {
+                    reporter.printError(getText("doclet.Option_doclint_no_qualifiers"));
+                    return false;
+                }
+                if (!DocLint.isValidOption(
+                        opt.replace("-xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX))) {
+                    reporter.printError(getText("doclet.Option_doclint_invalid_arg"));
+                    return false;
+                }
             }
         }
         return true;
@@ -506,8 +533,8 @@
      */
     @Override
     public Locale getLocale() {
-        if (root instanceof com.sun.tools.javadoc.RootDocImpl)
-            return ((com.sun.tools.javadoc.RootDocImpl)root).getLocale();
+        if (root instanceof RootDocImpl)
+            return ((RootDocImpl)root).getLocale();
         else
             return Locale.getDefault();
     }
@@ -518,8 +545,8 @@
     @Override
     public JavaFileManager getFileManager() {
         if (fileManager == null) {
-            if (root instanceof com.sun.tools.javadoc.RootDocImpl)
-                fileManager = ((com.sun.tools.javadoc.RootDocImpl)root).getFileManager();
+            if (root instanceof RootDocImpl)
+                fileManager = ((RootDocImpl) root).getFileManager();
             else
                 fileManager = new JavacFileManager(new Context(), false, null);
         }
@@ -527,4 +554,12 @@
     }
 
     private JavaFileManager fileManager;
+
+    @Override
+    public boolean showMessage(SourcePosition pos, String key) {
+        if (root instanceof RootDocImpl) {
+            return pos == null || ((RootDocImpl) root).showTagMessages();
+        }
+        return true;
+    }
 }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/ConstructorWriterImpl.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -137,6 +137,7 @@
             addName(constructor.name(), pre);
         }
         addParameters(constructor, pre);
+        writer.addReceiverAnnotationInfo(constructor, pre);
         addExceptions(constructor, pre);
         return pre;
     }
--- a/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1730,6 +1730,17 @@
     }
 
     /**
+     * Add the annotation types of the executable receiver.
+     *
+     * @param method the executable to write the receiver annotations for.
+     * @param htmltree the documentation tree to which the annotation info will be
+     *        added
+     */
+    public void addReceiverAnnotationInfo(ExecutableMemberDoc method, Content htmltree) {
+        addAnnotationInfo(method, method.receiverAnnotations(), htmltree);
+    }
+
+    /**
      * Adds the annotatation types for the given doc.
      *
      * @param doc the package to write annotations for
@@ -1799,6 +1810,26 @@
      *         documented.
      */
     private List<String> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak) {
+        return getAnnotations(indent, descList, linkBreak, true);
+    }
+
+    /**
+     * Return the string representations of the annotation types for
+     * the given doc.
+     *
+     * A {@code null} {@code elementType} indicates that all the
+     * annotations should be returned without any filtering.
+     *
+     * @param indent the number of extra spaces to indent the annotations.
+     * @param descList the array of {@link AnnotationDesc}.
+     * @param linkBreak if true, add new line between each member value.
+     * @param elementType the type of targeted element (used for filtering
+     *        type annotations from declaration annotations)
+     * @return an array of strings representing the annotations being
+     *         documented.
+     */
+    public List<String> getAnnotations(int indent, AnnotationDesc[] descList, boolean linkBreak,
+            boolean isJava5DeclarationLocation) {
         List<String> results = new ArrayList<String>();
         StringBuilder annotation;
         for (int i = 0; i < descList.length; i++) {
@@ -1812,6 +1843,11 @@
                     (!isAnnotationDocumented && !isContainerDocumented)) {
                 continue;
             }
+            /* TODO: check logic here to correctly handle declaration
+             * and type annotations.
+            if  (Util.isDeclarationAnnotation(annotationDoc, isJava5DeclarationLocation)) {
+                continue;
+            }*/
             annotation = new StringBuilder();
             isAnnotationDocumented = false;
             LinkInfoImpl linkInfo = new LinkInfoImpl(configuration,
--- a/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/LinkFactoryImpl.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 
 package com.sun.tools.doclets.formats.html;
 
+import java.util.List;
+
 import com.sun.javadoc.*;
 import com.sun.tools.doclets.internal.toolkit.*;
 import com.sun.tools.doclets.internal.toolkit.util.*;
@@ -123,11 +125,50 @@
         typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
         typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
         typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
+        typeLinkInfo.isJava5DeclarationLocation = false;
         LinkOutput output = getLinkOutput(typeLinkInfo);
         ((LinkInfoImpl) linkInfo).displayLength += typeLinkInfo.displayLength;
         return output;
     }
 
+    protected LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
+            AnnotationDesc annotation) {
+        throw new RuntimeException("Not implemented yet!");
+    }
+
+    public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
+        LinkOutput output = getOutputInstance();
+        AnnotationDesc[] annotations;
+        if (linkInfo.type instanceof AnnotatedType) {
+            annotations = linkInfo.type.asAnnotatedType().annotations();
+        } else if (linkInfo.type instanceof TypeVariable) {
+            annotations = linkInfo.type.asTypeVariable().annotations();
+        } else {
+            return output;
+        }
+
+        if (annotations.length == 0)
+            return output;
+
+        List<String> annos = m_writer.getAnnotations(0, annotations, false, linkInfo.isJava5DeclarationLocation);
+
+        boolean isFirst = true;
+        for (String anno : annos) {
+            if (!isFirst) {
+                linkInfo.displayLength += 1;
+                output.append(" ");
+                isFirst = false;
+            }
+            output.append(anno);
+        }
+        if (!annos.isEmpty()) {
+            linkInfo.displayLength += 1;
+            output.append(" ");
+        }
+
+        return output;
+    }
+
     /**
      * Given a class, return the appropriate tool tip.
      *
--- a/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/LinkInfoImpl.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -459,6 +459,8 @@
 
             case CONTEXT_RETURN_TYPE:
             case CONTEXT_SUMMARY_RETURN_TYPE:
+                excludeTypeBounds = true;
+                break;
             case CONTEXT_EXECUTABLE_MEMBER_PARAM:
                 excludeTypeBounds = true;
                 break;
--- a/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/formats/html/MethodWriterImpl.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -130,6 +130,7 @@
             addName(method.name(), pre);
         }
         addParameters(method, pre);
+        addReceiverAnnotations(method, pre);
         addExceptions(method, pre);
         return pre;
     }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -781,4 +781,6 @@
         sourcetab = n;
         tabSpaces = String.format("%" + n + "s", "");
     }
+
+    public abstract boolean showMessage(SourcePosition pos, String key);
 }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties	Sat Jan 26 19:24:46 2013 -0800
@@ -11,6 +11,8 @@
 doclet.Class_0_extends_implements_serializable=Class {0} extends {1} implements Serializable
 doclet.Option_conflict=Option {0} conflicts with {1}
 doclet.Option_reuse=Option reused: {0}
+doclet.Option_doclint_no_qualifiers=Access qualifiers not permitted for -Xdoclint arguments
+doclet.Option_doclint_invalid_arg=Invalid argument for -Xdoclint option
 doclet.exception_encountered= {0} encountered \n\
 \twhile attempting to create file: {1}
 doclet.perform_copy_exception_encountered= {0} encountered while \n\
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/MessageRetriever.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,9 +60,9 @@
     private ResourceBundle messageRB;
 
     /**
-     * Initilize the ResourceBundle with the given resource.
+     * Initialize the ResourceBundle with the given resource.
      *
-     * @param rb the esource bundle to read.
+     * @param rb the resource bundle to read.
      */
     public MessageRetriever(ResourceBundle rb) {
         this.configuration = null;
@@ -71,7 +71,7 @@
     }
 
     /**
-     * Initilize the ResourceBundle with the given resource.
+     * Initialize the ResourceBundle with the given resource.
      *
      * @param configuration the configuration
      * @param resourcelocation Resource.
@@ -189,7 +189,8 @@
      * @param args arguments to be replaced in the message.
      */
     public void warning(SourcePosition pos, String key, Object... args) {
-        printWarning(pos, getText(key, args));
+        if (configuration.showMessage(pos, key))
+            printWarning(pos, getText(key, args));
     }
 
     /**
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,11 @@
 package com.sun.tools.doclets.internal.toolkit.util;
 
 import java.io.*;
+import java.lang.annotation.ElementType;
 import java.util.*;
 
 import com.sun.javadoc.*;
+import com.sun.javadoc.AnnotationDesc.ElementValuePair;
 import com.sun.tools.doclets.internal.toolkit.*;
 import javax.tools.StandardLocation;
 
@@ -304,9 +306,7 @@
         //Try walking the tree.
         addAllInterfaceTypes(results,
             superType,
-            superType instanceof ClassDoc ?
-                ((ClassDoc) superType).interfaceTypes() :
-                ((ParameterizedType) superType).interfaceTypes(),
+            interfaceTypesOf(superType),
             false, configuration);
         List<Type> resultsList = new ArrayList<Type>(results.values());
         if (sort) {
@@ -315,6 +315,14 @@
         return resultsList;
     }
 
+    private static Type[] interfaceTypesOf(Type type) {
+        if (type instanceof AnnotatedType)
+            type = ((AnnotatedType)type).underlyingType();
+        return type instanceof ClassDoc ?
+                ((ClassDoc)type).interfaceTypes() :
+                ((ParameterizedType)type).interfaceTypes();
+    }
+
     public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
         return getAllInterfaces(type, configuration, true);
     }
@@ -325,9 +333,7 @@
         if (superType == null)
             return;
         addAllInterfaceTypes(results, superType,
-                superType instanceof ClassDoc ?
-                ((ClassDoc) superType).interfaceTypes() :
-                ((ParameterizedType) superType).interfaceTypes(),
+                interfaceTypesOf(superType),
                 raw, configuration);
     }
 
@@ -337,9 +343,7 @@
         if (superType == null)
             return;
         addAllInterfaceTypes(results, superType,
-                superType instanceof ClassDoc ?
-                ((ClassDoc) superType).interfaceTypes() :
-                ((ParameterizedType) superType).interfaceTypes(),
+                interfaceTypesOf(superType),
                 false, configuration);
     }
 
@@ -363,6 +367,9 @@
                 results.put(superInterface.asClassDoc(), superInterface);
             }
         }
+        if (type instanceof AnnotatedType)
+            type = ((AnnotatedType)type).underlyingType();
+
         if (type instanceof ParameterizedType)
             findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
         else if (((ClassDoc) type).typeParameters().length == 0)
@@ -494,6 +501,57 @@
         return false;
     }
 
+    private static boolean isDeclarationTarget(AnnotationDesc targetAnno) {
+        // The error recovery steps here are analogous to TypeAnnotations
+        ElementValuePair[] elems = targetAnno.elementValues();
+        if (elems == null
+            || elems.length != 1
+            || !"value".equals(elems[0].element().name())
+            || !(elems[0].value().value() instanceof AnnotationValue[]))
+            return true;    // error recovery
+
+        AnnotationValue[] values = (AnnotationValue[])elems[0].value().value();
+        for (int i = 0; i < values.length; i++) {
+            Object value = values[i].value();
+            if (!(value instanceof FieldDoc))
+                return true; // error recovery
+
+            FieldDoc eValue = (FieldDoc)value;
+            if (Util.isJava5DeclarationElementType(eValue)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true if the {@code annotationDoc} is to be treated
+     * as a declaration annotation, when targeting the
+     * {@code elemType} element type.
+     *
+     * @param annotationDoc the annotationDoc to check
+     * @param elemType  the targeted elemType
+     * @return true if annotationDoc is a declaration annotation
+     */
+    public static boolean isDeclarationAnnotation(AnnotationTypeDoc annotationDoc,
+            boolean isJava5DeclarationLocation) {
+        if (!isJava5DeclarationLocation)
+            return false;
+        AnnotationDesc[] annotationDescList = annotationDoc.annotations();
+        // Annotations with no target are treated as declaration as well
+        if (annotationDescList.length==0)
+            return true;
+        for (int i = 0; i < annotationDescList.length; i++) {
+            if (annotationDescList[i].annotationType().qualifiedName().equals(
+                    java.lang.annotation.Target.class.getName())) {
+                if (isDeclarationTarget(annotationDescList[i]))
+                    return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Return true if this class is linkable and false if we can't link to the
      * desired class.
@@ -662,4 +720,25 @@
         }
         return false;
     }
+
+    /**
+     * Test whether the given FieldDoc is one of the declaration annotation ElementTypes
+     * defined in Java 5.
+     * Instead of testing for one of the new enum constants added in Java 8, test for
+     * the old constants. This prevents bootstrapping problems.
+     *
+     * @param elt The FieldDoc to test
+     * @return true, iff the given ElementType is one of the constants defined in Java 5
+     * @since 1.8
+     */
+    public static boolean isJava5DeclarationElementType(FieldDoc elt) {
+        return elt.name().contentEquals(ElementType.ANNOTATION_TYPE.name()) ||
+                elt.name().contentEquals(ElementType.CONSTRUCTOR.name()) ||
+                elt.name().contentEquals(ElementType.FIELD.name()) ||
+                elt.name().contentEquals(ElementType.LOCAL_VARIABLE.name()) ||
+                elt.name().contentEquals(ElementType.METHOD.name()) ||
+                elt.name().contentEquals(ElementType.PACKAGE.name()) ||
+                elt.name().contentEquals(ElementType.PARAMETER.name()) ||
+                elt.name().contentEquals(ElementType.TYPE.name());
+    }
 }
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkFactory.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,11 @@
                 //Just a primitive.
                 linkInfo.displayLength += type.typeName().length();
                 linkOutput.append(type.typeName());
+            } else if (type.asAnnotatedType() != null) {
+                linkOutput.append(getTypeAnnotationLinks(linkInfo));
+                linkInfo.type = type.asAnnotatedType().underlyingType();
+                linkOutput.append(getLinkOutput(linkInfo));
+                return linkOutput;
             } else if (type.asWildcardType() != null) {
                 //Wildcard type.
                 linkInfo.isTypeBound = true;
@@ -82,6 +87,7 @@
                     linkOutput.append(getLinkOutput(linkInfo));
                 }
             } else if (type.asTypeVariable()!= null) {
+                linkOutput.append(getTypeAnnotationLinks(linkInfo));
                 linkInfo.isTypeBound = true;
                 //A type variable.
                 Doc owner = type.asTypeVariable().owner();
@@ -175,6 +181,9 @@
     protected abstract LinkOutput getTypeParameterLink(LinkInfo linkInfo,
         Type typeParam);
 
+    protected abstract LinkOutput getTypeAnnotationLink(LinkInfo linkInfo,
+            AnnotationDesc annotation);
+
     /**
      * Return the links to the type parameters.
      *
@@ -226,6 +235,24 @@
         return output;
     }
 
+    public LinkOutput getTypeAnnotationLinks(LinkInfo linkInfo) {
+        LinkOutput output = getOutputInstance();
+        if (linkInfo.type.asAnnotatedType() == null)
+            return output;
+        AnnotationDesc[] annotations = linkInfo.type.asAnnotatedType().annotations();
+        for (int i = 0; i < annotations.length; i++) {
+            if (i > 0) {
+                linkInfo.displayLength += 1;
+                output.append(" ");
+            }
+            output.append(getTypeAnnotationLink(linkInfo, annotations[i]));
+        }
+
+        linkInfo.displayLength += 1;
+        output.append(" ");
+        return output;
+    }
+
     /**
      * Return &amp;lt;, which is used in type parameters.  Override this
      * if your doclet uses something different.
--- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/links/LinkInfo.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,6 +69,12 @@
     public boolean isTypeBound = false;
 
     /**
+     * Whether the document element is in a Java 5 declaration
+     * location or not.
+     */
+    public boolean isJava5DeclarationLocation = true;
+
+    /**
      * The label for the link.
      */
     public String label;
--- a/src/share/classes/com/sun/tools/doclint/Checker.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclint/Checker.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 
 package com.sun.tools.doclint;
 
+import com.sun.source.doctree.LiteralTree;
 import java.util.regex.Matcher;
 import com.sun.source.doctree.LinkTree;
 import java.net.URI;
@@ -91,10 +92,11 @@
     boolean foundInheritDoc = false;
     boolean foundReturn = false;
 
-    enum Flag {
+    public enum Flag {
         TABLE_HAS_CAPTION,
         HAS_ELEMENT,
-        HAS_TEXT
+        HAS_TEXT,
+        REPORTED_BAD_INLINE
     }
 
     static class TagStackItem {
@@ -194,7 +196,8 @@
 
     @Override
     public Void visitText(TextTree tree, Void ignore) {
-        if (!tree.getBody().trim().isEmpty()) {
+        if (hasNonWhitespace(tree)) {
+            checkAllowsText(tree);
             markEnclosingTag(Flag.HAS_TEXT);
         }
         return null;
@@ -202,6 +205,7 @@
 
     @Override
     public Void visitEntity(EntityTree tree, Void ignore) {
+        checkAllowsText(tree);
         markEnclosingTag(Flag.HAS_TEXT);
         String name = tree.getName().toString();
         if (name.startsWith("#")) {
@@ -217,6 +221,18 @@
         return null;
     }
 
+    void checkAllowsText(DocTree tree) {
+        TagStackItem top = tagStack.peek();
+        if (top != null
+                && top.tree.getKind() == DocTree.Kind.START_ELEMENT
+                && !top.tag.acceptsText()) {
+            if (top.flags.add(Flag.REPORTED_BAD_INLINE)) {
+                env.messages.error(HTML, tree, "dc.text.not.allowed",
+                        ((StartElementTree) top.tree).getName());
+            }
+        }
+    }
+
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="HTML elements">
@@ -229,53 +245,22 @@
         if (t == null) {
             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
         } else {
+            for (TagStackItem tsi: tagStack) {
+                if (tsi.tag.accepts(t)) {
+                    while (tagStack.peek() != tsi) tagStack.pop();
+                    break;
+                } else if (tsi.tag.endKind != HtmlTag.EndKind.OPTIONAL)
+                    break;
+            }
+
+            checkStructure(tree, t);
+
             // tag specific checks
             switch (t) {
                 // check for out of sequence headers, such as <h1>...</h1>  <h3>...</h3>
                 case H1: case H2: case H3: case H4: case H5: case H6:
                     checkHeader(tree, t);
                     break;
-                // <p> inside <pre>
-                case P:
-                    TagStackItem top = tagStack.peek();
-                    if (top != null && top.tag == HtmlTag.PRE)
-                        env.messages.warning(HTML, tree, "dc.tag.p.in.pre");
-                    break;
-            }
-
-            // check that only block tags and inline tags are used,
-            // and that blocks tags are not used within inline tags
-            switch (t.blockType) {
-                case INLINE:
-                    break;
-                case BLOCK:
-                    TagStackItem top = tagStack.peek();
-                    if (top != null && top.tag != null && top.tag.blockType == HtmlTag.BlockType.INLINE) {
-                        switch (top.tree.getKind()) {
-                            case START_ELEMENT: {
-                                Name name = ((StartElementTree) top.tree).getName();
-                                env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.element",
-                                        treeName, name);
-                                break;
-                            }
-                            case LINK:
-                            case LINK_PLAIN: {
-                                String name = top.tree.getKind().tagName;
-                                env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.tag",
-                                        treeName, name);
-                                break;
-                            }
-                            default:
-                                env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.other",
-                                        treeName);
-                        }
-                    }
-                    break;
-                case OTHER:
-                    env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
-                    break;
-                default:
-                    throw new AssertionError();
             }
 
             if (t.flags.contains(HtmlTag.Flag.NO_NEST)) {
@@ -323,6 +308,58 @@
         }
     }
 
+    private void checkStructure(StartElementTree tree, HtmlTag t) {
+        Name treeName = tree.getName();
+        TagStackItem top = tagStack.peek();
+        switch (t.blockType) {
+            case BLOCK:
+                if (top == null || top.tag.accepts(t))
+                    return;
+
+                switch (top.tree.getKind()) {
+                    case START_ELEMENT: {
+                        if (top.tag.blockType == HtmlTag.BlockType.INLINE) {
+                            Name name = ((StartElementTree) top.tree).getName();
+                            env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.element",
+                                    treeName, name);
+                            return;
+                        }
+                    }
+                    break;
+
+                    case LINK:
+                    case LINK_PLAIN: {
+                        String name = top.tree.getKind().tagName;
+                        env.messages.error(HTML, tree, "dc.tag.not.allowed.inline.tag",
+                                treeName, name);
+                        return;
+                    }
+                }
+                break;
+
+            case INLINE:
+                if (top == null || top.tag.accepts(t))
+                    return;
+                break;
+
+            case LIST_ITEM:
+            case TABLE_ITEM:
+                if (top != null) {
+                    // reset this flag so subsequent bad inline content gets reported
+                    top.flags.remove(Flag.REPORTED_BAD_INLINE);
+                    if (top.tag.accepts(t))
+                        return;
+                }
+                break;
+
+            case OTHER:
+                env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName);
+                return;
+        }
+
+        env.messages.error(HTML, tree, "dc.tag.not.allowed.here", treeName);
+    }
+
     private void checkHeader(StartElementTree tree, HtmlTag tag) {
         // verify the new tag
         if (getHeaderLevel(tag) > getHeaderLevel(currHeaderTag) + 1) {
@@ -359,9 +396,8 @@
             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
         } else if (t.endKind == HtmlTag.EndKind.NONE) {
             env.messages.error(HTML, tree, "dc.tag.end.not.permitted", treeName);
-        } else if (tagStack.isEmpty()) {
-            env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
         } else {
+            boolean done = false;
             while (!tagStack.isEmpty()) {
                 TagStackItem top = tagStack.peek();
                 if (t == top.tag) {
@@ -378,11 +414,8 @@
                             && !top.flags.contains(Flag.HAS_ELEMENT)) {
                         env.messages.warning(HTML, tree, "dc.tag.empty", treeName);
                     }
-                    if (t.flags.contains(HtmlTag.Flag.NO_TEXT)
-                            && top.flags.contains(Flag.HAS_TEXT)) {
-                        env.messages.error(HTML, tree, "dc.text.not.allowed", treeName);
-                    }
                     tagStack.pop();
+                    done = true;
                     break;
                 } else if (top.tag == null || top.tag.endKind != HtmlTag.EndKind.REQUIRED) {
                     tagStack.pop();
@@ -400,10 +433,15 @@
                         tagStack.pop();
                     } else {
                         env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+                        done = true;
                         break;
                     }
                 }
             }
+
+            if (!done && tagStack.isEmpty()) {
+                env.messages.error(HTML, tree, "dc.tag.end.unexpected", treeName);
+            }
         }
 
         return super.visitEndElement(tree, ignore);
@@ -447,14 +485,18 @@
                         if (currTag != HtmlTag.A) {
                             break;
                         }
-                    // fallthrough
+                        // fallthrough
                     case ID:
                         String value = getAttrValue(tree);
-                        if (!validName.matcher(value).matches()) {
-                            env.messages.error(HTML, tree, "dc.invalid.anchor", value);
-                        }
-                        if (!foundAnchors.add(value)) {
-                            env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+                        if (value == null) {
+                            env.messages.error(HTML, tree, "dc.anchor.value.missing");
+                        } else {
+                            if (!validName.matcher(value).matches()) {
+                                env.messages.error(HTML, tree, "dc.invalid.anchor", value);
+                            }
+                            if (!foundAnchors.add(value)) {
+                                env.messages.error(HTML, tree, "dc.anchor.already.defined", value);
+                            }
                         }
                         break;
 
@@ -542,6 +584,19 @@
     }
 
     @Override
+    public Void visitLiteral(LiteralTree tree, Void ignore) {
+        if (tree.getKind() == DocTree.Kind.CODE) {
+            for (TagStackItem tsi: tagStack) {
+                if (tsi.tag == HtmlTag.CODE) {
+                    env.messages.warning(HTML, tree, "dc.tag.code.within.code");
+                    break;
+                }
+            }
+        }
+        return super.visitLiteral(tree, ignore);
+    }
+
+    @Override
     public Void visitParam(ParamTree tree, Void ignore) {
         boolean typaram = tree.isTypeParameter();
         IdentifierTree nameTree = tree.getName();
@@ -740,7 +795,7 @@
         for (DocTree d: list) {
             switch (d.getKind()) {
                 case TEXT:
-                    if (!((TextTree) d).getBody().trim().isEmpty())
+                    if (hasNonWhitespace((TextTree) d))
                         return;
                     break;
                 default:
@@ -749,6 +804,16 @@
         }
         env.messages.warning(SYNTAX, tree, "dc.empty", tree.getKind().tagName);
     }
+
+    boolean hasNonWhitespace(TextTree tree) {
+        String s = tree.getBody();
+        for (int i = 0; i < s.length(); i++) {
+            if (!Character.isWhitespace(s.charAt(i)))
+                return true;
+        }
+        return false;
+    }
+
     // </editor-fold>
 
 }
--- a/src/share/classes/com/sun/tools/doclint/DocLint.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclint/DocLint.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,7 +122,7 @@
 
         if (javacFiles.isEmpty()) {
             if (!needHelp)
-                System.out.println("no files given");
+                out.println("no files given");
         }
 
         JavacTool tool = JavacTool.create();
@@ -179,11 +179,11 @@
                 }
             } else if (arg.equals(STATS)) {
                 env.messages.setStatsEnabled(true);
-            } else if (arg.matches("-bootclasspath") && i + 1 < args.length) {
+            } else if (arg.equals("-bootclasspath") && i + 1 < args.length) {
                 javacBootClassPath = splitPath(args[++i]);
-            } else if (arg.matches("-classpath") && i + 1 < args.length) {
+            } else if (arg.equals("-classpath") && i + 1 < args.length) {
                 javacClassPath = splitPath(args[++i]);
-            } else if (arg.matches("-sourcepath") && i + 1 < args.length) {
+            } else if (arg.equals("-sourcepath") && i + 1 < args.length) {
                 javacSourcePath = splitPath(args[++i]);
             } else if (arg.equals(XMSGS_OPTION)) {
                 env.messages.setOptions(null);
@@ -234,6 +234,8 @@
         out.println("    equivalent to -Xmsgs:all/protected, meaning that");
         out.println("    all messages are reported for protected and public");
         out.println("    declarations only. ");
+        out.println("  -stats");
+        out.println("    Report statistics on the reported issues.");
         out.println("  -h -help --help -usage -?");
         out.println("    Show this message.");
         out.println("");
@@ -247,7 +249,7 @@
 
     List<File> splitPath(String path) {
         List<File> files = new ArrayList<File>();
-        for (String f: path.split(File.separator)) {
+        for (String f: path.split(File.pathSeparator)) {
             if (f.length() > 0)
                 files.add(new File(f));
         }
--- a/src/share/classes/com/sun/tools/doclint/Entity.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclint/Entity.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
  * risk.  This code and its internal interfaces are subject to change
  * or deletion without notice.</b></p>
  */
-enum Entity {
+public enum Entity {
     nbsp(160),
     iexcl(161),
     cent(162),
--- a/src/share/classes/com/sun/tools/doclint/HtmlTag.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclint/HtmlTag.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,16 +57,22 @@
     B(BlockType.INLINE, EndKind.REQUIRED,
             EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
 
-    BLOCKQUOTE,
+    BIG(BlockType.INLINE, EndKind.REQUIRED,
+            EnumSet.of(Flag.EXPECT_CONTENT)),
+
+    BLOCKQUOTE(BlockType.BLOCK, EndKind.REQUIRED,
+            EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
 
     BODY(BlockType.OTHER, EndKind.REQUIRED),
 
     BR(BlockType.INLINE, EndKind.NONE,
             attrs(AttrKind.USE_CSS, CLEAR)),
 
-    CAPTION(EnumSet.of(Flag.EXPECT_CONTENT)),
+    CAPTION(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+            EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
 
-    CENTER,
+    CENTER(BlockType.BLOCK, EndKind.REQUIRED,
+            EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
 
     CITE(BlockType.INLINE, EndKind.REQUIRED,
             EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
@@ -74,17 +80,23 @@
     CODE(BlockType.INLINE, EndKind.REQUIRED,
             EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
 
-    DD(BlockType.BLOCK, EndKind.OPTIONAL,
-            EnumSet.of(Flag.EXPECT_CONTENT)),
+    DD(BlockType.LIST_ITEM, EndKind.OPTIONAL,
+            EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
 
-    DIV,
+    DIV(BlockType.BLOCK, EndKind.REQUIRED,
+            EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
 
     DL(BlockType.BLOCK, EndKind.REQUIRED,
-            EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
-            attrs(AttrKind.USE_CSS, COMPACT)),
+            EnumSet.of(Flag.EXPECT_CONTENT),
+            attrs(AttrKind.USE_CSS, COMPACT)) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == DT) || (t == DD);
+        }
+    },
 
-    DT(BlockType.BLOCK, EndKind.OPTIONAL,
-            EnumSet.of(Flag.EXPECT_CONTENT)),
+    DT(BlockType.LIST_ITEM, EndKind.OPTIONAL,
+            EnumSet.of(Flag.ACCEPTS_INLINE, Flag.EXPECT_CONTENT)),
 
     EM(BlockType.INLINE, EndKind.REQUIRED,
             EnumSet.of(Flag.NO_NEST)),
@@ -97,12 +109,12 @@
 
     FRAMESET(BlockType.OTHER, EndKind.REQUIRED),
 
-    H1,
-    H2,
-    H3,
-    H4,
-    H5,
-    H6,
+    H1(BlockType.BLOCK, EndKind.REQUIRED),
+    H2(BlockType.BLOCK, EndKind.REQUIRED),
+    H3(BlockType.BLOCK, EndKind.REQUIRED),
+    H4(BlockType.BLOCK, EndKind.REQUIRED),
+    H5(BlockType.BLOCK, EndKind.REQUIRED),
+    H6(BlockType.BLOCK, EndKind.REQUIRED),
 
     HEAD(BlockType.OTHER, EndKind.REQUIRED),
 
@@ -118,31 +130,54 @@
             attrs(AttrKind.OBSOLETE, NAME),
             attrs(AttrKind.USE_CSS, ALIGN, HSPACE, VSPACE, BORDER)),
 
-    LI(BlockType.BLOCK, EndKind.OPTIONAL),
+    LI(BlockType.LIST_ITEM, EndKind.OPTIONAL,
+            EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE)),
 
     LINK(BlockType.OTHER, EndKind.NONE),
 
-    MENU,
+    MENU(BlockType.BLOCK, EndKind.REQUIRED) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == LI);
+        }
+    },
 
     META(BlockType.OTHER, EndKind.NONE),
 
     NOFRAMES(BlockType.OTHER, EndKind.REQUIRED),
 
-    NOSCRIPT(BlockType.OTHER, EndKind.REQUIRED),
+    NOSCRIPT(BlockType.BLOCK, EndKind.REQUIRED),
 
     OL(BlockType.BLOCK, EndKind.REQUIRED,
-            EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
-            attrs(AttrKind.USE_CSS, START, TYPE)),
+            EnumSet.of(Flag.EXPECT_CONTENT),
+            attrs(AttrKind.USE_CSS, START, TYPE)){
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == LI);
+        }
+    },
 
     P(BlockType.BLOCK, EndKind.OPTIONAL,
             EnumSet.of(Flag.EXPECT_CONTENT),
             attrs(AttrKind.USE_CSS, ALIGN)),
 
-    PRE(EnumSet.of(Flag.EXPECT_CONTENT)),
+    PRE(BlockType.BLOCK, EndKind.REQUIRED,
+            EnumSet.of(Flag.EXPECT_CONTENT)) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            switch (t) {
+                case IMG: case BIG: case SMALL: case SUB: case SUP:
+                    return false;
+                default:
+                    return (t.blockType == BlockType.INLINE);
+            }
+        }
+    },
 
     SCRIPT(BlockType.OTHER, EndKind.REQUIRED),
 
-    SMALL(BlockType.INLINE, EndKind.REQUIRED),
+    SMALL(BlockType.INLINE, EndKind.REQUIRED,
+            EnumSet.of(Flag.EXPECT_CONTENT)),
 
     SPAN(BlockType.INLINE, EndKind.REQUIRED,
             EnumSet.of(Flag.EXPECT_CONTENT)),
@@ -157,37 +192,70 @@
             EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
 
     TABLE(BlockType.BLOCK, EndKind.REQUIRED,
-            EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
+            EnumSet.of(Flag.EXPECT_CONTENT),
             attrs(AttrKind.OK, SUMMARY, Attr.FRAME, RULES, BORDER,
                 CELLPADDING, CELLSPACING),
-            attrs(AttrKind.USE_CSS, ALIGN, WIDTH, BGCOLOR)),
+            attrs(AttrKind.USE_CSS, ALIGN, WIDTH, BGCOLOR)) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            switch (t) {
+                case CAPTION:
+                case THEAD: case TBODY: case TFOOT:
+                case TR: // HTML 3.2
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    },
 
-    TBODY(BlockType.BLOCK, EndKind.REQUIRED,
-            EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
-            attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)),
+    TBODY(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+            EnumSet.of(Flag.EXPECT_CONTENT),
+            attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == TR);
+        }
+    },
 
-    TD(BlockType.BLOCK, EndKind.OPTIONAL,
+    TD(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
+            EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE),
             attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS,
                 ALIGN, CHAR, CHAROFF, VALIGN),
             attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)),
 
-    TFOOT(BlockType.BLOCK, EndKind.REQUIRED,
-            attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)),
+    TFOOT(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+            attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == TR);
+        }
+    },
 
-    TH(BlockType.BLOCK, EndKind.OPTIONAL,
+    TH(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
+            EnumSet.of(Flag.ACCEPTS_BLOCK, Flag.ACCEPTS_INLINE),
             attrs(AttrKind.OK, COLSPAN, ROWSPAN, HEADERS, SCOPE, ABBR, AXIS,
                 ALIGN, CHAR, CHAROFF, VALIGN),
             attrs(AttrKind.USE_CSS, WIDTH, BGCOLOR, HEIGHT, NOWRAP)),
 
-    THEAD(BlockType.BLOCK, EndKind.REQUIRED,
-            attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)),
+    THEAD(BlockType.TABLE_ITEM, EndKind.REQUIRED,
+            attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN)) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == TR);
+        }
+    },
 
     TITLE(BlockType.OTHER, EndKind.REQUIRED),
 
-    TR(BlockType.BLOCK, EndKind.OPTIONAL,
-            EnumSet.of(Flag.NO_TEXT),
+    TR(BlockType.TABLE_ITEM, EndKind.OPTIONAL,
             attrs(AttrKind.OK, ALIGN, CHAR, CHAROFF, VALIGN),
-            attrs(AttrKind.USE_CSS, BGCOLOR)),
+            attrs(AttrKind.USE_CSS, BGCOLOR)) {
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == TH) || (t == TD);
+        }
+    },
 
     TT(BlockType.INLINE, EndKind.REQUIRED,
             EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
@@ -196,8 +264,13 @@
             EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_NEST)),
 
     UL(BlockType.BLOCK, EndKind.REQUIRED,
-            EnumSet.of(Flag.EXPECT_CONTENT, Flag.NO_TEXT),
-            attrs(AttrKind.USE_CSS, COMPACT, TYPE)),
+            EnumSet.of(Flag.EXPECT_CONTENT),
+            attrs(AttrKind.USE_CSS, COMPACT, TYPE)){
+        @Override
+        public boolean accepts(HtmlTag t) {
+            return (t == LI);
+        }
+    },
 
     VAR(BlockType.INLINE, EndKind.REQUIRED);
 
@@ -207,6 +280,8 @@
     public static enum BlockType {
         BLOCK,
         INLINE,
+        LIST_ITEM,
+        TABLE_ITEM,
         OTHER;
     }
 
@@ -220,9 +295,10 @@
     }
 
     public static enum Flag {
+        ACCEPTS_BLOCK,
+        ACCEPTS_INLINE,
         EXPECT_CONTENT,
-        NO_NEST,
-        NO_TEXT
+        NO_NEST
     }
 
     public static enum Attr {
@@ -273,7 +349,7 @@
         static final Map<String,Attr> index = new HashMap<String,Attr>();
         static {
             for (Attr t: values()) {
-                index.put(t.name().toLowerCase(), t);
+                index.put(t.getText(), t);
             }
         }
     }
@@ -300,22 +376,14 @@
     public final Set<Flag> flags;
     private final Map<Attr,AttrKind> attrs;
 
-
-    HtmlTag() {
-        this(BlockType.BLOCK, EndKind.REQUIRED);
-    }
-
-    HtmlTag(Set<Flag> flags) {
-        this(BlockType.BLOCK, EndKind.REQUIRED, flags);
-    }
-
     HtmlTag(BlockType blockType, EndKind endKind, AttrMap... attrMaps) {
         this(blockType, endKind, Collections.<Flag>emptySet(), attrMaps);
     }
 
     HtmlTag(BlockType blockType, EndKind endKind, Set<Flag> flags, AttrMap... attrMaps) {
         this.blockType = blockType;
-        this.endKind = endKind;this.flags = flags;
+        this.endKind = endKind;
+        this.flags = flags;
         this.attrs = new EnumMap<Attr,AttrKind>(Attr.class);
         for (Map<Attr,AttrKind> m: attrMaps)
             this.attrs.putAll(m);
@@ -324,6 +392,35 @@
         attrs.put(Attr.STYLE, AttrKind.OK);
     }
 
+    public boolean accepts(HtmlTag t) {
+        if (flags.contains(Flag.ACCEPTS_BLOCK) && flags.contains(Flag.ACCEPTS_INLINE)) {
+            return (t.blockType == BlockType.BLOCK) || (t.blockType == BlockType.INLINE);
+        } else if (flags.contains(Flag.ACCEPTS_BLOCK)) {
+            return (t.blockType == BlockType.BLOCK);
+        } else if (flags.contains(Flag.ACCEPTS_INLINE)) {
+            return (t.blockType == BlockType.INLINE);
+        } else
+            switch (blockType) {
+                case BLOCK:
+                case INLINE:
+                    return (t.blockType == BlockType.INLINE);
+                case OTHER:
+                    // OTHER tags are invalid in doc comments, and will be
+                    // reported separately, so silently accept/ignore any content
+                    return true;
+                default:
+                    // any combination which could otherwise arrive here
+                    // ought to have been handled in an overriding method
+                    throw new AssertionError(this + ":" + t);
+            }
+    }
+
+    public boolean acceptsText() {
+        // generally, anywhere we can put text we can also put inline tag
+        // so check if a typical inline tag is allowed
+        return accepts(B);
+    }
+
     public String getText() {
         return name().toLowerCase();
     }
@@ -346,7 +443,7 @@
     private static final Map<String,HtmlTag> index = new HashMap<String,HtmlTag>();
     static {
         for (HtmlTag t: values()) {
-            index.put(t.name().toLowerCase(), t);
+            index.put(t.getText(), t);
         }
     }
 
--- a/src/share/classes/com/sun/tools/doclint/resources/doclint.properties	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/doclint/resources/doclint.properties	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 #
 
 dc.anchor.already.defined = anchor already defined: {0}
+dc.anchor.value.missing = no value given for anchor
 dc.attr.lacks.value = attribute lacks value
 dc.attr.obsolete = attribute obsolete: {0}
 dc.attr.obsolete.use.css = attribute obsolete, use CSS instead: {0}
@@ -47,12 +48,14 @@
 dc.no.summary.or.caption.for.table=no summary or caption for table
 dc.param.name.not.found = @param name not found
 dc.ref.not.found = reference not found
+dc.tag.code.within.code = '{@code'} within <code>
 dc.tag.empty = empty <{0}> tag
 dc.tag.end.not.permitted = invalid end tag: </{0}>
 dc.tag.end.unexpected = unexpected end tag: </{0}>
 dc.tag.header.sequence.1 = header used out of sequence: <{0}>
 dc.tag.header.sequence.2 = header used out of sequence: <{0}>
 dc.tag.nested.not.allowed=nested tag not allowed: <{0}>
+dc.tag.not.allowed.here = tag not allowed here: <{0}>
 dc.tag.not.allowed = element not allowed in documentation comments: <{0}>
 dc.tag.not.allowed.inline.element = block element not allowed within inline element <{1}>: {0}
 dc.tag.not.allowed.inline.tag = block element not allowed within @{1}: {0}
--- a/src/share/classes/com/sun/tools/javac/code/Annotations.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Annotations.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,7 @@
  *
  * An instance of this class can be in one of three states:
  *
- * NOT_STARTED indicates that the Symbol this instance belongs to have not been
+ * NOT_STARTED indicates that the Symbol this instance belongs to has not been
  * annotated (yet). Specifically if the declaration is not annotated this
  * instance will never move past NOT_STARTED. You can never go back to
  * NOT_STARTED.
@@ -59,7 +59,7 @@
  *
  * "unnamed" this Annotations contains some attributes, possibly the final set.
  * While in this state you can only prepend or append to the attributes not set
- * it directly. You can also move back to the IN_PROGRESS sate using reset().
+ * it directly. You can also move back to the IN_PROGRESS state using reset().
  *
  * <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
@@ -67,14 +67,21 @@
  */
 public class Annotations {
 
-    private static final List<Attribute.Compound> NOT_STARTED = List.of(null);
-    private static final List<Attribute.Compound> IN_PROGRESS = List.of(null);
+    private static final List<Attribute.Compound> DECL_NOT_STARTED = List.of(null);
+    private static final List<Attribute.Compound> DECL_IN_PROGRESS = List.of(null);
+
     /*
      * This field should never be null
      */
-    private List<Attribute.Compound> attributes = NOT_STARTED;
+    private List<Attribute.Compound> attributes = DECL_NOT_STARTED;
+
     /*
-     * The Symbol this Annotations belong to
+     * This field should never be null
+     */
+    private List<Attribute.TypeCompound> type_attributes = List.<Attribute.TypeCompound>nil();
+
+    /*
+     * The Symbol this Annotations instance belongs to
      */
     private final Symbol sym;
 
@@ -82,11 +89,15 @@
         this.sym = sym;
     }
 
-    public List<Attribute.Compound> getAttributes() {
-        return filterSentinels(attributes);
+    public List<Attribute.Compound> getDeclarationAttributes() {
+        return filterDeclSentinels(attributes);
     }
 
-    public void setAttributes(List<Attribute.Compound> a) {
+    public List<Attribute.TypeCompound> getTypeAttributes() {
+        return type_attributes;
+    }
+
+    public void setDeclarationAttributes(List<Attribute.Compound> a) {
         Assert.check(pendingCompletion() || !isStarted());
         if (a == null) {
             throw new NullPointerException();
@@ -94,31 +105,51 @@
         attributes = a;
     }
 
+    public void setTypeAttributes(List<Attribute.TypeCompound> a) {
+        if (a == null) {
+            throw new NullPointerException();
+        }
+        type_attributes = a;
+    }
+
     public void setAttributes(Annotations other) {
         if (other == null) {
             throw new NullPointerException();
         }
-        setAttributes(other.getAttributes());
+        setDeclarationAttributes(other.getDeclarationAttributes());
+        setTypeAttributes(other.getTypeAttributes());
     }
 
-    public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) {
+    public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
         Assert.check(pendingCompletion() || (!isStarted() && sym.kind == PCK));
+        this.setDeclarationAttributes(getAttributesForCompletion(ctx));
+    }
 
-        Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated = ctx.annotated;
+    public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
+        this.appendUniqueTypes(getAttributesForCompletion(ctx));
+    }
+
+    private <T extends Attribute.Compound> List<T> getAttributesForCompletion(
+            final Annotate.AnnotateRepeatedContext<T> ctx) {
+
+        Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = ctx.annotated;
         boolean atLeastOneRepeated = false;
-        List<Attribute.Compound> buf = List.<Attribute.Compound>nil();
-        for (ListBuffer<Attribute.Compound> lb : annotated.values()) {
+        List<T> buf = List.<T>nil();
+        for (ListBuffer<T> lb : annotated.values()) {
             if (lb.size() == 1) {
                 buf = buf.prepend(lb.first());
             } else { // repeated
-                buf = buf.prepend(new Placeholder(lb.toList(), sym));
+                // This will break when other subtypes of Attributs.Compound
+                // are introduced, because PlaceHolder is a subtype of TypeCompound.
+                T res;
+                @SuppressWarnings("unchecked")
+                T ph = (T) new Placeholder<T>(ctx, lb.toList(), sym);
+                res = ph;
+                buf = buf.prepend(res);
                 atLeastOneRepeated = true;
             }
         }
 
-        // Add non-repeating attributes
-        setAttributes(buf.reverse());
-
         if (atLeastOneRepeated) {
             // The Symbol s is now annotated with a combination of
             // finished non-repeating annotations and placeholders for
@@ -126,19 +157,18 @@
             //
             // We need to do this in two passes because when creating
             // a container for a repeating annotation we must
-            // guarantee that the @ContainedBy on the
+            // guarantee that the @Repeatable on the
             // contained annotation is fully annotated
             //
             // The way we force this order is to do all repeating
             // annotations in a pass after all non-repeating are
-            // finished. This will work because @ContainedBy
+            // finished. This will work because @Repeatable
             // is non-repeating and therefore will be annotated in the
             // fist pass.
 
             // Queue a pass that will replace Attribute.Placeholders
             // with Attribute.Compound (made from synthesized containers).
             ctx.annotateRepeated(new Annotate.Annotator() {
-
                 @Override
                 public String toString() {
                     return "repeated annotation pass of: " + sym + " in: " + sym.owner;
@@ -150,10 +180,12 @@
                 }
             });
         }
+        // Add non-repeating attributes
+        return buf.reverse();
     }
 
     public Annotations reset() {
-        attributes = IN_PROGRESS;
+        attributes = DECL_IN_PROGRESS;
         return this;
     }
 
@@ -163,12 +195,16 @@
                 || attributes.isEmpty();
     }
 
+    public boolean isTypesEmpty() {
+        return type_attributes.isEmpty();
+    }
+
     public boolean pendingCompletion() {
-        return attributes == IN_PROGRESS;
+        return attributes == DECL_IN_PROGRESS;
     }
 
     public Annotations append(List<Attribute.Compound> l) {
-        attributes = filterSentinels(attributes);
+        attributes = filterDeclSentinels(attributes);
 
         if (l.isEmpty()) {
             ; // no-op
@@ -180,8 +216,24 @@
         return this;
     }
 
+    public Annotations appendUniqueTypes(List<Attribute.TypeCompound> l) {
+        if (l.isEmpty()) {
+            ; // no-op
+        } else if (type_attributes.isEmpty()) {
+            type_attributes = l;
+        } else {
+            // TODO: in case we expect a large number of annotations, this
+            // might be inefficient.
+            for (Attribute.TypeCompound tc : l) {
+                if (!type_attributes.contains(tc))
+                    type_attributes = type_attributes.append(tc);
+            }
+        }
+        return this;
+    }
+
     public Annotations prepend(List<Attribute.Compound> l) {
-        attributes = filterSentinels(attributes);
+        attributes = filterDeclSentinels(attributes);
 
         if (l.isEmpty()) {
             ; // no-op
@@ -193,19 +245,29 @@
         return this;
     }
 
-    private List<Attribute.Compound> filterSentinels(List<Attribute.Compound> a) {
-        return (a == IN_PROGRESS || a == NOT_STARTED)
+    private List<Attribute.Compound> filterDeclSentinels(List<Attribute.Compound> a) {
+        return (a == DECL_IN_PROGRESS || a == DECL_NOT_STARTED)
                 ? List.<Attribute.Compound>nil()
                 : a;
     }
 
     private boolean isStarted() {
-        return attributes != NOT_STARTED;
+        return attributes != DECL_NOT_STARTED;
     }
 
     private List<Attribute.Compound> getPlaceholders() {
         List<Attribute.Compound> res = List.<Attribute.Compound>nil();
-        for (Attribute.Compound a : filterSentinels(attributes)) {
+        for (Attribute.Compound a : filterDeclSentinels(attributes)) {
+            if (a instanceof Placeholder) {
+                res = res.prepend(a);
+            }
+        }
+        return res.reverse();
+    }
+
+    private List<Attribute.TypeCompound> getTypePlaceholders() {
+        List<Attribute.TypeCompound> res = List.<Attribute.TypeCompound>nil();
+        for (Attribute.TypeCompound a : type_attributes) {
             if (a instanceof Placeholder) {
                 res = res.prepend(a);
             }
@@ -216,68 +278,100 @@
     /*
      * Replace Placeholders for repeating annotations with their containers
      */
-    private void complete(Annotate.AnnotateRepeatedContext ctx) {
-        Assert.check(!pendingCompletion());
+    private <T extends Attribute.Compound> void complete(Annotate.AnnotateRepeatedContext<T> ctx) {
         Log log = ctx.log;
         Env<AttrContext> env = ctx.env;
         JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
         try {
+            // TODO: can we reduce duplication in the following branches?
+            if (ctx.isTypeCompound) {
+                Assert.check(!isTypesEmpty());
 
-            if (isEmpty()) {
-                return;
+                if (isTypesEmpty()) {
+                    return;
+                }
+
+                List<Attribute.TypeCompound> result = List.nil();
+                for (Attribute.TypeCompound a : getTypeAttributes()) {
+                    if (a instanceof Placeholder) {
+                        @SuppressWarnings("unchecked")
+                        Placeholder<Attribute.TypeCompound> ph = (Placeholder<Attribute.TypeCompound>) a;
+                        Attribute.TypeCompound replacement = replaceOne(ph, ph.getRepeatedContext());
+
+                        if (null != replacement) {
+                            result = result.prepend(replacement);
+                        }
+                    } else {
+                        result = result.prepend(a);
+                    }
+                }
+
+                type_attributes = result.reverse();
+
+                Assert.check(Annotations.this.getTypePlaceholders().isEmpty());
+            } else {
+                Assert.check(!pendingCompletion());
+
+                if (isEmpty()) {
+                    return;
+                }
+
+                List<Attribute.Compound> result = List.nil();
+                for (Attribute.Compound a : getDeclarationAttributes()) {
+                    if (a instanceof Placeholder) {
+                        @SuppressWarnings("unchecked")
+                        Attribute.Compound replacement = replaceOne((Placeholder<T>) a, ctx);
+
+                        if (null != replacement) {
+                            result = result.prepend(replacement);
+                        }
+                    } else {
+                        result = result.prepend(a);
+                    }
+                }
+
+                attributes = result.reverse();
+
+                Assert.check(Annotations.this.getPlaceholders().isEmpty());
             }
-
-            List<Attribute.Compound> result = List.nil();
-            for (Attribute.Compound a : getAttributes()) {
-                if (a instanceof Placeholder) {
-                    Attribute.Compound replacement = replaceOne((Placeholder) a, ctx);
-
-                    if (null != replacement) {
-                        result = result.prepend(replacement);
-                    }
-                } else {
-                    result = result.prepend(a);
-                }
-            }
-
-            attributes = result.reverse();
-
-            Assert.check(Annotations.this.getPlaceholders().isEmpty());
         } finally {
             log.useSource(oldSource);
         }
     }
 
-    private Attribute.Compound replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) {
+    private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, Annotate.AnnotateRepeatedContext<T> ctx) {
         Log log = ctx.log;
 
         // Process repeated annotations
-        Attribute.Compound validRepeated =
-            ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
+        T validRepeated = ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor(), sym);
 
         if (validRepeated != null) {
             // Check that the container isn't manually
             // present along with repeated instances of
             // its contained annotation.
-            ListBuffer<Attribute.Compound> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
+            ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
             if (manualContainer != null) {
-                log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present",
+                log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
                         manualContainer.first().type.tsym);
             }
         }
 
         // A null return will delete the Placeholder
         return validRepeated;
-
     }
 
-    private static class Placeholder extends Attribute.Compound {
+    private static class Placeholder<T extends Attribute.Compound> extends Attribute.TypeCompound {
 
-        private List<Attribute.Compound> placeholderFor;
-        private Symbol on;
+        private final Annotate.AnnotateRepeatedContext<T> ctx;
+        private final List<T> placeholderFor;
+        private final Symbol on;
 
-        public Placeholder(List<Attribute.Compound> placeholderFor, Symbol on) {
-            super(Type.noType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
+        public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
+            super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
+                    ctx.isTypeCompound ?
+                            ((Attribute.TypeCompound)placeholderFor.head).position :
+                                null);
+            this.ctx = ctx;
             this.placeholderFor = placeholderFor;
             this.on = on;
         }
@@ -287,8 +381,12 @@
             return "<placeholder: " + placeholderFor + " on: " + on + ">";
         }
 
-        public List<Attribute.Compound> getPlaceholderFor() {
+        public List<T> getPlaceholderFor() {
             return placeholderFor;
         }
+
+        public Annotate.AnnotateRepeatedContext<T> getRepeatedContext() {
+            return ctx;
+        }
     }
 }
--- a/src/share/classes/com/sun/tools/javac/code/Attribute.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Attribute.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -217,6 +217,21 @@
         }
     }
 
+    public static class TypeCompound extends Compound {
+        public TypeAnnotationPosition position;
+        public TypeCompound(Compound compound,
+                TypeAnnotationPosition position) {
+            this(compound.type, compound.values, position);
+        }
+        public TypeCompound(Type type,
+                List<Pair<MethodSymbol, Attribute>> values,
+                TypeAnnotationPosition position) {
+            super(type, values);
+            this.position = position;
+        }
+
+    }
+
     /** The value for an annotation element of an array type.
      */
     public static class Array extends Attribute {
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -233,23 +233,23 @@
     public static final long PROPRIETARY = 1L<<38;
 
     /**
-     * Flag that marks a a multi-catch parameter
+     * Flag that marks a multi-catch parameter.
      */
     public static final long UNION = 1L<<39;
 
     /**
-     * Flag that marks a special kind of bridge methods (the ones that
-     * come from restricted supertype bounds)
+     * Flag that marks a special kind of bridge method (the ones that
+     * come from restricted supertype bounds).
      */
     public static final long OVERRIDE_BRIDGE = 1L<<40;
 
     /**
-     * Flag that marks an 'effectively final' local variable
+     * Flag that marks an 'effectively final' local variable.
      */
     public static final long EFFECTIVELY_FINAL = 1L<<41;
 
     /**
-     * Flag that marks non-override equivalent methods with the same signature
+     * Flag that marks non-override equivalent methods with the same signature.
      */
     public static final long CLASH = 1L<<42;
 
@@ -280,7 +280,7 @@
                                 SYNCHRONIZED | FINAL | STRICTFP;
     public static final long
         ExtendedStandardFlags       = (long)StandardFlags | DEFAULT,
-        InterfaceDefaultMethodMask  = ABSTRACT | PUBLIC | STRICTFP | SYNCHRONIZED | DEFAULT,
+        InterfaceMethodMask         = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
         LocalVarFlags               = FINAL | PARAMETER;
 
 
--- a/src/share/classes/com/sun/tools/javac/code/Lint.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Lint.java	Sat Jan 26 19:24:46 2013 -0800
@@ -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
@@ -74,7 +74,7 @@
      * the given annotations.
      */
     public Lint augment(Annotations annots) {
-        return augmentor.augment(this, annots.getAttributes());
+        return augmentor.augment(this, annots.getDeclarationAttributes());
     }
 
     /**
@@ -82,7 +82,7 @@
      * the given annotations and flags.
      */
     public Lint augment(Annotations annots, long flags) {
-        Lint l = augmentor.augment(this, annots.getAttributes());
+        Lint l = augmentor.augment(this, annots.getDeclarationAttributes());
         if ((flags & DEPRECATED) != 0) {
             if (l == this)
                 l = new Lint(this);
--- a/src/share/classes/com/sun/tools/javac/code/Printer.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Printer.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,10 @@
 
 import java.util.Locale;
 
+import javax.lang.model.type.TypeKind;
+
 import com.sun.tools.javac.api.Messages;
+import com.sun.tools.javac.code.Type.AnnotatedType;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.util.List;
@@ -35,7 +38,6 @@
 
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
-import static com.sun.tools.javac.code.TypeTag.ARRAY;
 import static com.sun.tools.javac.code.TypeTag.CLASS;
 import static com.sun.tools.javac.code.TypeTag.FORALL;
 
@@ -188,7 +190,7 @@
         StringBuilder buf = new StringBuilder();
         if (t.getEnclosingType().tag == CLASS && t.tsym.owner.kind == Kinds.TYP) {
             buf.append(visit(t.getEnclosingType(), locale));
-            buf.append(".");
+            buf.append('.');
             buf.append(className(t, false, locale));
         } else {
             buf.append(className(t, true, locale));
@@ -196,7 +198,7 @@
         if (t.getTypeArguments().nonEmpty()) {
             buf.append('<');
             buf.append(visitTypes(t.getTypeArguments(), locale));
-            buf.append(">");
+            buf.append('>');
         }
         return buf.toString();
     }
@@ -231,6 +233,17 @@
         return visitType(t, locale);
     }
 
+    @Override
+    public String visitAnnotatedType(AnnotatedType t, Locale locale) {
+        if (t.typeAnnotations != null &&
+                t.typeAnnotations.nonEmpty()) {
+            // TODO: better logic for arrays, ...
+            return "(" + t.typeAnnotations + " :: " + visit(t.underlyingType, locale) + ")";
+        } else {
+            return "({} :: " + visit(t.underlyingType, locale) + ")";
+        }
+    }
+
     public String visitType(Type t, Locale locale) {
         String s = (t.tsym == null || t.tsym.name == null)
                 ? localize(locale, "compiler.misc.type.none")
@@ -296,8 +309,13 @@
                 args = args.tail;
                 buf.append(',');
             }
-            if (args.head.tag == ARRAY) {
-                buf.append(visit(((ArrayType) args.head).elemtype, locale));
+            if (args.head.unannotatedType().getKind() == TypeKind.ARRAY) {
+                buf.append(visit(((ArrayType) args.head.unannotatedType()).elemtype, locale));
+                if (args.head.getAnnotations().nonEmpty()) {
+                    buf.append(' ');
+                    buf.append(args.head.getAnnotations());
+                    buf.append(' ');
+                }
                 buf.append("...");
             } else {
                 buf.append(visit(args.head, locale));
--- a/src/share/classes/com/sun/tools/javac/code/Source.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -176,9 +176,6 @@
     public boolean allowTryWithResources() {
         return compareTo(JDK1_7) >= 0;
     }
-    public boolean allowTypeAnnotations() {
-        return compareTo(JDK1_7) >= 0;
-    }
     public boolean allowBinaryLiterals() {
         return compareTo(JDK1_7) >= 0;
     }
@@ -206,18 +203,30 @@
     public boolean allowDefaultMethods() {
         return compareTo(JDK1_8) >= 0;
     }
+    public boolean allowStaticInterfaceMethods() {
+        return compareTo(JDK1_8) >= 0;
+    }
     public boolean allowStrictMethodClashCheck() {
         return compareTo(JDK1_8) >= 0;
     }
     public boolean allowEffectivelyFinalInInnerClasses() {
         return compareTo(JDK1_8) >= 0;
     }
+    public boolean allowTypeAnnotations() {
+        return compareTo(JDK1_8) >= 0;
+    }
     public boolean allowRepeatedAnnotations() {
         return compareTo(JDK1_8) >= 0;
     }
     public boolean allowIntersectionTypesInCast() {
         return compareTo(JDK1_8) >= 0;
     }
+    public boolean allowEarlyReturnConstraints() {
+        return compareTo(JDK1_8) >= 0;
+    }
+    public boolean allowStructuralMostSpecific() {
+        return compareTo(JDK1_8) >= 0;
+    }
     public static SourceVersion toSourceVersion(Source source) {
         switch(source) {
         case JDK1_2:
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,7 +84,15 @@
      *  method to make sure that the class symbol is loaded.
      */
     public List<Attribute.Compound> getRawAttributes() {
-        return annotations.getAttributes();
+        return annotations.getDeclarationAttributes();
+    }
+
+    /** An accessor method for the type attributes of this symbol.
+     *  Attributes of class symbols should be accessed through the accessor
+     *  method to make sure that the class symbol is loaded.
+     */
+    public List<Attribute.TypeCompound> getRawTypeAttributes() {
+        return annotations.getTypeAttributes();
     }
 
     /** Fetch a particular annotation from a symbol. */
@@ -450,11 +458,19 @@
      * This is the implementation for {@code
      * javax.lang.model.element.Element.getAnnotationMirrors()}.
      */
-    public final List<Attribute.Compound> getAnnotationMirrors() {
+    public final List<? extends AnnotationMirror> getAnnotationMirrors() {
         return getRawAttributes();
     }
 
     /**
+     * TODO: Should there be a {@code
+     * javax.lang.model.element.Element.getTypeAnnotationMirrors()}.
+     */
+    public final List<Attribute.TypeCompound> getTypeAnnotationMirrors() {
+        return getRawTypeAttributes();
+    }
+
+    /**
      * @deprecated this method should never be used by javac internally.
      */
     @Deprecated
@@ -462,6 +478,11 @@
         return JavacElements.getAnnotation(this, annoType);
     }
 
+    // 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) {
+        return JavacElements.getAnnotations(this, annoType);
+    }
+
     // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
     public java.util.List<Symbol> getEnclosedElements() {
         return List.nil();
@@ -790,6 +811,12 @@
             return super.getRawAttributes();
         }
 
+        @Override
+        public List<Attribute.TypeCompound> getRawTypeAttributes() {
+            if (completer != null) complete();
+            return super.getRawTypeAttributes();
+        }
+
         public Type erasure(Types types) {
             if (erasure_field == null)
                 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
@@ -1228,7 +1255,8 @@
             case Flags.PRIVATE:
                 return false;
             case Flags.PUBLIC:
-                return true;
+                return !this.owner.isInterface() ||
+                        (flags_field & STATIC) == 0;
             case Flags.PROTECTED:
                 return (origin.flags() & INTERFACE) == 0;
             case 0:
@@ -1242,6 +1270,18 @@
             }
         }
 
+        @Override
+        public boolean isInheritedIn(Symbol clazz, Types types) {
+            switch ((int)(flags_field & Flags.AccessFlags)) {
+                case PUBLIC:
+                    return !this.owner.isInterface() ||
+                            clazz == owner ||
+                            (flags_field & STATIC) == 0;
+                default:
+                    return super.isInheritedIn(clazz, types);
+            }
+        }
+
         /** The implementation of this (abstract) symbol in class origin;
          *  null if none exists. Synthetic methods are not considered
          *  as possible implementations.
@@ -1369,7 +1409,7 @@
             return defaultValue;
         }
 
-         public List<VarSymbol> getParameters() {
+        public List<VarSymbol> getParameters() {
             return params();
         }
 
--- a/src/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Symtab.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -161,10 +161,10 @@
     public final Type autoCloseableType;
     public final Type trustMeType;
     public final Type lambdaMetafactory;
-    public final Type containedByType;
-    public final Type containerForType;
+    public final Type repeatableType;
     public final Type documentedType;
     public final Type elementTypeType;
+    public final Type functionalInterfaceType;
 
     /** The symbol representing the length field of an array.
      */
@@ -494,8 +494,7 @@
         deprecatedType = enterClass("java.lang.Deprecated");
         suppressWarningsType = enterClass("java.lang.SuppressWarnings");
         inheritedType = enterClass("java.lang.annotation.Inherited");
-        containedByType = enterClass("java.lang.annotation.ContainedBy");
-        containerForType = enterClass("java.lang.annotation.ContainerFor");
+        repeatableType = enterClass("java.lang.annotation.Repeatable");
         documentedType = enterClass("java.lang.annotation.Documented");
         elementTypeType = enterClass("java.lang.annotation.ElementType");
         systemType = enterClass("java.lang.System");
@@ -509,6 +508,7 @@
         nativeHeaderType = enterClass("java.lang.annotation.Native");
         nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader");
         lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
+        functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
 
         synthesizeEmptyInterfaceIfMissing(autoCloseableType);
         synthesizeEmptyInterfaceIfMissing(cloneableType);
--- a/src/share/classes/com/sun/tools/javac/code/TargetType.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/TargetType.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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,7 @@
 
 package com.sun.tools.javac.code;
 
-import java.util.EnumSet;
-import java.util.Set;
-
-import static com.sun.tools.javac.code.TargetType.TargetAttribute.*;
+import com.sun.tools.javac.util.Assert;
 
 /**
  * Describes the type of program element an extended annotation (or extended
@@ -44,178 +41,89 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
+// Code duplicated in com.sun.tools.classfile.TypeAnnotation.TargetType
 public enum TargetType {
+    /** For annotations on a class type parameter declaration. */
+    CLASS_TYPE_PARAMETER(0x00),
 
-    //
-    // Some target types are commented out, because Java doesn't permit such
-    // targets.  They are included here to confirm that their omission is
-    // intentional omission not an accidental omission.
-    //
+    /** For annotations on a method type parameter declaration. */
+    METHOD_TYPE_PARAMETER(0x01),
 
-    /** For annotations on typecasts. */
-    TYPECAST(0x00, IsLocal),
+    /** For annotations on the type of an "extends" or "implements" clause. */
+    CLASS_EXTENDS(0x10),
 
-    /** For annotations on a type argument or nested array of a typecast. */
-    TYPECAST_GENERIC_OR_ARRAY(0x01, HasLocation, IsLocal),
+    /** For annotations on a bound of a type parameter of a class. */
+    CLASS_TYPE_PARAMETER_BOUND(0x11),
 
-    /** For annotations on type tests. */
-    INSTANCEOF(0x02, IsLocal),
+    /** For annotations on a bound of a type parameter of a method. */
+    METHOD_TYPE_PARAMETER_BOUND(0x12),
 
-    /** For annotations on a type argument or nested array of a type test. */
-    INSTANCEOF_GENERIC_OR_ARRAY(0x03, HasLocation, IsLocal),
+    /** For annotations on a field. */
+    FIELD(0x13),
 
-    /** For annotations on object creation expressions. */
-    NEW(0x04, IsLocal),
-
-    /**
-     * For annotations on a type argument or nested array of an object creation
-     * expression.
-     */
-    NEW_GENERIC_OR_ARRAY(0x05, HasLocation, IsLocal),
-
+    /** For annotations on a method return type. */
+    METHOD_RETURN(0x14),
 
     /** For annotations on the method receiver. */
-    METHOD_RECEIVER(0x06),
+    METHOD_RECEIVER(0x15),
 
-    // invalid location
-    //@Deprecated METHOD_RECEIVER_GENERIC_OR_ARRAY(0x07, HasLocation),
-
-    /** For annotations on local variables. */
-    LOCAL_VARIABLE(0x08, IsLocal),
-
-    /** For annotations on a type argument or nested array of a local. */
-    LOCAL_VARIABLE_GENERIC_OR_ARRAY(0x09, HasLocation, IsLocal),
-
-    // handled by regular annotations
-    //@Deprecated METHOD_RETURN(0x0A),
-
-    /**
-     * For annotations on a type argument or nested array of a method return
-     * type.
-     */
-    METHOD_RETURN_GENERIC_OR_ARRAY(0x0B, HasLocation),
-
-    // handled by regular annotations
-    //@Deprecated METHOD_PARAMETER(0x0C),
-
-    /** For annotations on a type argument or nested array of a method parameter. */
-    METHOD_PARAMETER_GENERIC_OR_ARRAY(0x0D, HasLocation),
-
-    // handled by regular annotations
-    //@Deprecated FIELD(0x0E),
-
-    /** For annotations on a type argument or nested array of a field. */
-    FIELD_GENERIC_OR_ARRAY(0x0F, HasLocation),
-
-    /** For annotations on a bound of a type parameter of a class. */
-    CLASS_TYPE_PARAMETER_BOUND(0x10, HasBound, HasParameter),
-
-    /**
-     * For annotations on a type argument or nested array of a bound of a type
-     * parameter of a class.
-     */
-    CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x11, HasBound, HasLocation, HasParameter),
-
-    /** For annotations on a bound of a type parameter of a method. */
-    METHOD_TYPE_PARAMETER_BOUND(0x12, HasBound, HasParameter),
-
-    /**
-     * For annotations on a type argument or nested array of a bound of a type
-     * parameter of a method.
-     */
-    METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY(0x13, HasBound, HasLocation, HasParameter),
-
-    /** For annotations on the type of an "extends" or "implements" clause. */
-    CLASS_EXTENDS(0x14),
-
-    /** For annotations on the inner type of an "extends" or "implements" clause. */
-    CLASS_EXTENDS_GENERIC_OR_ARRAY(0x15, HasLocation),
+    /** For annotations on a method parameter. */
+    METHOD_FORMAL_PARAMETER(0x16),
 
     /** For annotations on a throws clause in a method declaration. */
-    THROWS(0x16),
+    THROWS(0x17),
 
-    // invalid location
-    //@Deprecated THROWS_GENERIC_OR_ARRAY(0x17, HasLocation),
+    /** For annotations on a local variable. */
+    LOCAL_VARIABLE(0x40, true),
 
-    /** For annotations in type arguments of object creation expressions. */
-    NEW_TYPE_ARGUMENT(0x18, IsLocal),
-    NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x19, HasLocation, IsLocal),
+    /** For annotations on a resource variable. */
+    RESOURCE_VARIABLE(0x41, true),
 
-    METHOD_TYPE_ARGUMENT(0x1A, IsLocal),
-    METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY(0x1B, HasLocation, IsLocal),
+    /** For annotations on an exception parameter. */
+    EXCEPTION_PARAMETER(0x42, true),
 
-    WILDCARD_BOUND(0x1C, HasBound),
-    WILDCARD_BOUND_GENERIC_OR_ARRAY(0x1D, HasBound, HasLocation),
+    /** For annotations on a typecast. */
+    CAST(0x43, true),
 
-    CLASS_LITERAL(0x1E, IsLocal),
-    CLASS_LITERAL_GENERIC_OR_ARRAY(0x1F, HasLocation, IsLocal),
+    /** For annotations on a type test. */
+    INSTANCEOF(0x44, true),
 
-    METHOD_TYPE_PARAMETER(0x20, HasParameter),
+    /** For annotations on an object creation expression. */
+    NEW(0x45, true),
 
-    // invalid location
-    //@Deprecated METHOD_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x21, HasLocation, HasParameter),
+    /** For annotations on a type argument of an object creation expression. */
+    CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true),
 
-    CLASS_TYPE_PARAMETER(0x22, HasParameter),
+    /** For annotations on a type argument of a method call. */
+    METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true),
 
-    // invalid location
-    //@Deprecated CLASS_TYPE_PARAMETER_GENERIC_OR_ARRAY(0x23, HasLocation, HasParameter),
+    /** 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 method reference. */
+    METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true),
 
     /** For annotations with an unknown target. */
-    UNKNOWN(-1);
+    UNKNOWN(0xFF);
 
-    static final int MAXIMUM_TARGET_TYPE_VALUE = 0x22;
+    private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x92;
 
     private final int targetTypeValue;
-    private final Set<TargetAttribute> flags;
+    private final boolean isLocal;
 
-    TargetType(int targetTypeValue, TargetAttribute... attributes) {
-        if (targetTypeValue < Byte.MIN_VALUE
-                || targetTypeValue > Byte.MAX_VALUE)
-                throw new AssertionError("attribute type value needs to be a byte: " + targetTypeValue);
-        this.targetTypeValue = (byte)targetTypeValue;
-        flags = EnumSet.noneOf(TargetAttribute.class);
-        for (TargetAttribute attr : attributes)
-            flags.add(attr);
+    private TargetType(int targetTypeValue) {
+        this(targetTypeValue, false);
     }
 
-    /**
-     * Returns whether or not this TargetType represents an annotation whose
-     * target is an inner type of a generic or array type.
-     *
-     * @return true if this TargetType represents an annotation on an inner
-     *         type, false otherwise
-     */
-    public boolean hasLocation() {
-        return flags.contains(HasLocation);
-    }
-
-    public TargetType getGenericComplement() {
-        if (hasLocation())
-            return this;
-        else
-            return fromTargetTypeValue(targetTypeValue() + 1);
-    }
-
-    /**
-     * Returns whether or not this TargetType represents an annotation whose
-     * target has a parameter index.
-     *
-     * @return true if this TargetType has a parameter index,
-     *         false otherwise
-     */
-    public boolean hasParameter() {
-        return flags.contains(HasParameter);
-    }
-
-    /**
-     * Returns whether or not this TargetType represents an annotation whose
-     * target is a type parameter bound.
-     *
-     * @return true if this TargetType represents an type parameter bound
-     *         annotation, false otherwise
-     */
-    public boolean hasBound() {
-        return flags.contains(HasBound);
+    private TargetType(int targetTypeValue, boolean isLocal) {
+        if (targetTypeValue < 0
+                || targetTypeValue > 255)
+                Assert.error("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue));
+        this.targetTypeValue = targetTypeValue;
+        this.isLocal = isLocal;
     }
 
     /**
@@ -226,7 +134,7 @@
      * member declaration signature tree
      */
     public boolean isLocal() {
-        return flags.contains(IsLocal);
+        return isLocal;
     }
 
     public int targetTypeValue() {
@@ -239,7 +147,7 @@
         targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
         TargetType[] alltargets = values();
         for (TargetType target : alltargets) {
-            if (target.targetTypeValue >= 0)
+            if (target.targetTypeValue != UNKNOWN.targetTypeValue)
                 targets[target.targetTypeValue] = target;
         }
         for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) {
@@ -249,22 +157,18 @@
     }
 
     public static boolean isValidTargetTypeValue(int tag) {
-        if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
+        if (tag == UNKNOWN.targetTypeValue)
             return true;
 
         return (tag >= 0 && tag < targets.length);
     }
 
     public static TargetType fromTargetTypeValue(int tag) {
-        if (((byte)tag) == ((byte)UNKNOWN.targetTypeValue))
+        if (tag == UNKNOWN.targetTypeValue)
             return UNKNOWN;
 
         if (tag < 0 || tag >= targets.length)
-            throw new IllegalArgumentException("Unknown TargetType: " + tag);
+            Assert.error("Unknown TargetType: " + tag);
         return targets[tag];
     }
-
-    static enum TargetAttribute {
-        HasLocation, HasParameter, HasBound, IsLocal;
-    }
 }
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 import java.util.Map;
 import java.util.Set;
 
+import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.type.*;
 
 import com.sun.tools.javac.code.Symbol.*;
@@ -87,7 +88,7 @@
      */
     protected TypeTag tag;
 
-    /** The defining class / interface / package / type variable
+    /** The defining class / interface / package / type variable.
      */
     public TypeSymbol tsym;
 
@@ -166,7 +167,7 @@
     /**
      * Get the representation of this type used for modelling purposes.
      * By default, this is itself. For ErrorType, a different value
-     * may be provided,
+     * may be provided.
      */
     public Type getModelType() {
         return this;
@@ -245,6 +246,14 @@
         return this;
     }
 
+    /**
+     * If this is an annotated type, return the underlying type.
+     * Otherwise, return the type itself.
+     */
+    public Type unannotatedType() {
+        return this;
+    }
+
     /** Return the base types of a list of types.
      */
     public static List<Type> baseTypes(List<Type> ts) {
@@ -339,8 +348,11 @@
             args = args.tail;
             buf.append(',');
         }
-        if (args.head.tag == ARRAY) {
-            buf.append(((ArrayType)args.head).elemtype);
+        if (args.head.unannotatedType().tag == ARRAY) {
+            buf.append(((ArrayType)args.head.unannotatedType()).elemtype);
+            if (args.head.getAnnotations().nonEmpty()) {
+                buf.append(args.head.getAnnotations());
+            }
             buf.append("...");
         } else {
             buf.append(args.head);
@@ -350,10 +362,12 @@
 
     /** Access methods.
      */
+    public List<? extends AnnotationMirror> getAnnotations() { return List.nil(); }
     public List<Type>        getTypeArguments()  { return List.nil(); }
-    public Type              getEnclosingType() { return null; }
+    public Type              getEnclosingType()  { return null; }
     public List<Type>        getParameterTypes() { return List.nil(); }
     public Type              getReturnType()     { return null; }
+    public Type              getReceiverType()   { return null; }
     public List<Type>        getThrownTypes()    { return List.nil(); }
     public Type              getUpperBound()     { return null; }
     public Type              getLowerBound()     { return null; }
@@ -600,7 +614,7 @@
 
         /** The enclosing type of this type. If this is the type of an inner
          *  class, outer_field refers to the type of its enclosing
-         *  instance class, in all other cases it referes to noType.
+         *  instance class, in all other cases it refers to noType.
          */
         private Type outer_field;
 
@@ -974,6 +988,10 @@
         public Type restype;
         public List<Type> thrown;
 
+        /** The type annotations on the method receiver.
+         */
+        public Type recvtype;
+
         public MethodType(List<Type> argtypes,
                           Type restype,
                           List<Type> thrown,
@@ -1000,6 +1018,7 @@
 
         public List<Type>        getParameterTypes() { return argtypes; }
         public Type              getReturnType()     { return restype; }
+        public Type              getReceiverType()   { return recvtype; }
         public List<Type>        getThrownTypes()    { return thrown; }
 
         public boolean isErroneous() {
@@ -1028,6 +1047,7 @@
             for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
                 l.head.complete();
             restype.complete();
+            recvtype.complete();
             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
                 l.head.complete();
         }
@@ -1112,7 +1132,11 @@
         }
 
         @Override
-        public Type getUpperBound() { return bound; }
+        public Type getUpperBound() {
+            if ((bound == null || bound.tag == NONE) && this != tsym.type)
+                bound = tsym.type.getUpperBound();
+            return bound;
+        }
 
         int rank_field = -1;
 
@@ -1183,6 +1207,7 @@
         public Type getEnclosingType() { return qtype.getEnclosingType(); }
         public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
         public Type getReturnType() { return qtype.getReturnType(); }
+        public Type getReceiverType() { return qtype.getReceiverType(); }
         public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
         public List<Type> allparams() { return qtype.allparams(); }
         public Type getUpperBound() { return qtype.getUpperBound(); }
@@ -1435,7 +1460,7 @@
         }
 
         public Type constType(Object constValue) { return this; }
-        public Type getEnclosingType()          { return this; }
+        public Type getEnclosingType()           { return this; }
         public Type getReturnType()              { return this; }
         public Type asSub(Symbol sym)            { return this; }
         public Type map(Mapping f)               { return this; }
@@ -1461,11 +1486,165 @@
         }
     }
 
+    public static class AnnotatedType extends Type
+            implements javax.lang.model.type.AnnotatedType {
+        /** The type annotations on this type.
+         */
+        public List<Attribute.TypeCompound> typeAnnotations;
+
+        /** The underlying type that is annotated.
+         */
+        public Type underlyingType;
+
+        public AnnotatedType(Type underlyingType) {
+            super(underlyingType.tag, underlyingType.tsym);
+            this.typeAnnotations = List.nil();
+            this.underlyingType = underlyingType;
+            Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED,
+                    "Can't annotate already annotated type: " + underlyingType);
+        }
+
+        public AnnotatedType(List<Attribute.TypeCompound> typeAnnotations,
+                Type underlyingType) {
+            super(underlyingType.tag, underlyingType.tsym);
+            this.typeAnnotations = typeAnnotations;
+            this.underlyingType = underlyingType;
+            Assert.check(underlyingType.getKind() != TypeKind.ANNOTATED,
+                    "Can't annotate already annotated type: " + underlyingType +
+                    "; adding: " + typeAnnotations);
+        }
+
+        @Override
+        public TypeKind getKind() {
+            return TypeKind.ANNOTATED;
+        }
+
+        @Override
+        public List<? extends AnnotationMirror> getAnnotations() {
+            return typeAnnotations;
+        }
+
+        @Override
+        public TypeMirror getUnderlyingType() {
+            return underlyingType;
+        }
+
+        @Override
+        public Type unannotatedType() {
+            return underlyingType;
+        }
+
+        @Override
+        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
+            return v.visitAnnotatedType(this, s);
+        }
+
+        @Override
+        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
+            return v.visitAnnotated(this, p);
+        }
+
+        @Override
+        public Type map(Mapping f) {
+            underlyingType.map(f);
+            return this;
+        }
+
+        @Override
+        public Type constType(Object constValue) { return underlyingType.constType(constValue); }
+        @Override
+        public Type getEnclosingType()           { return underlyingType.getEnclosingType(); }
+
+        @Override
+        public Type getReturnType()              { return underlyingType.getReturnType(); }
+        @Override
+        public List<Type> getTypeArguments()     { return underlyingType.getTypeArguments(); }
+        @Override
+        public List<Type> getParameterTypes()    { return underlyingType.getParameterTypes(); }
+        @Override
+        public Type getReceiverType()            { return underlyingType.getReceiverType(); }
+        @Override
+        public List<Type> getThrownTypes()       { return underlyingType.getThrownTypes(); }
+        @Override
+        public Type getUpperBound()              { return underlyingType.getUpperBound(); }
+        @Override
+        public Type getLowerBound()              { return underlyingType.getLowerBound(); }
+
+        @Override
+        public boolean isErroneous()             { return underlyingType.isErroneous(); }
+        @Override
+        public boolean isCompound()              { return underlyingType.isCompound(); }
+        @Override
+        public boolean isInterface()             { return underlyingType.isInterface(); }
+        @Override
+        public List<Type> allparams()            { return underlyingType.allparams(); }
+        @Override
+        public boolean isNumeric()               { return underlyingType.isNumeric(); }
+        @Override
+        public boolean isReference()             { return underlyingType.isReference(); }
+        @Override
+        public boolean isParameterized()         { return underlyingType.isParameterized(); }
+        @Override
+        public boolean isRaw()                   { return underlyingType.isRaw(); }
+        @Override
+        public boolean isFinal()                 { return underlyingType.isFinal(); }
+        @Override
+        public boolean isSuperBound()            { return underlyingType.isSuperBound(); }
+        @Override
+        public boolean isExtendsBound()          { return underlyingType.isExtendsBound(); }
+        @Override
+        public boolean isUnbound()               { return underlyingType.isUnbound(); }
+
+        @Override
+        public String toString() {
+            // TODO more logic for arrays, etc.
+            if (typeAnnotations != null &&
+                    !typeAnnotations.isEmpty()) {
+                return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
+            } else {
+                return "({} :: " + underlyingType.toString() +")";
+            }
+        }
+
+        @Override
+        public boolean contains(Type t)          { return underlyingType.contains(t); }
+
+        // TODO: attach annotations?
+        @Override
+        public Type withTypeVar(Type t)          { return underlyingType.withTypeVar(t); }
+
+        // TODO: attach annotations?
+        @Override
+        public TypeSymbol asElement()            { return underlyingType.asElement(); }
+
+        // TODO: attach annotations?
+        @Override
+        public MethodType asMethodType()         { return underlyingType.asMethodType(); }
+
+        @Override
+        public void complete()                   { underlyingType.complete(); }
+
+        @Override
+        public TypeMirror getComponentType()     { return ((ArrayType)underlyingType).getComponentType(); }
+
+        // The result is an ArrayType, but only in the model sense, not the Type sense.
+        public AnnotatedType makeVarargs() {
+            AnnotatedType atype = new AnnotatedType(((ArrayType)underlyingType).makeVarargs());
+            atype.typeAnnotations = this.typeAnnotations;
+            return atype;
+        }
+
+        @Override
+        public TypeMirror getExtendsBound()      { return ((WildcardType)underlyingType).getExtendsBound(); }
+        @Override
+        public TypeMirror getSuperBound()        { return ((WildcardType)underlyingType).getSuperBound(); }
+    }
+
     /**
      * A visitor for types.  A visitor is used to implement operations
      * (or relations) on types.  Most common operations on types are
      * binary relations and this interface is designed for binary
-     * relations, that is, operations on the form
+     * relations, that is, operations of the form
      * Type&nbsp;&times;&nbsp;S&nbsp;&rarr;&nbsp;R.
      * <!-- In plain text: Type x S -> R -->
      *
@@ -1486,6 +1665,7 @@
         R visitForAll(ForAll t, S s);
         R visitUndetVar(UndetVar t, S s);
         R visitErrorType(ErrorType t, S s);
+        R visitAnnotatedType(AnnotatedType t, S s);
         R visitType(Type t, S s);
     }
 }
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 
 package com.sun.tools.javac.code;
 
+import java.util.Iterator;
+
 import com.sun.tools.javac.util.*;
 
 /** A type annotation position.
@@ -34,12 +36,92 @@
 *  This code and its internal interfaces are subject to change or
 *  deletion without notice.</b>
 */
+// Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
 public class TypeAnnotationPosition {
 
+    public enum TypePathEntryKind {
+        ARRAY(0),
+        INNER_TYPE(1),
+        WILDCARD(2),
+        TYPE_ARGUMENT(3);
+
+        public final int tag;
+
+        private TypePathEntryKind(int tag) {
+            this.tag = tag;
+        }
+    }
+
+    public static class TypePathEntry {
+        /** The fixed number of bytes per TypePathEntry. */
+        public static final int bytesPerEntry = 2;
+
+        public final TypePathEntryKind tag;
+        public final int arg;
+
+        public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
+        public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
+        public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
+
+        private TypePathEntry(TypePathEntryKind tag) {
+            Assert.check(tag == TypePathEntryKind.ARRAY ||
+                    tag == TypePathEntryKind.INNER_TYPE ||
+                    tag == TypePathEntryKind.WILDCARD,
+                    "Invalid TypePathEntryKind: " + tag);
+            this.tag = tag;
+            this.arg = 0;
+        }
+
+        public TypePathEntry(TypePathEntryKind tag, int arg) {
+            Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT,
+                    "Invalid TypePathEntryKind: " + tag);
+            this.tag = tag;
+            this.arg = arg;
+        }
+
+        public static TypePathEntry fromBinary(int tag, int arg) {
+            Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag,
+                    "Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
+            switch (tag) {
+            case 0:
+                return ARRAY;
+            case 1:
+                return INNER_TYPE;
+            case 2:
+                return WILDCARD;
+            case 3:
+                return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
+            default:
+                Assert.error("Invalid TypePathEntryKind tag: " + tag);
+                return null;
+            }
+        }
+
+        @Override
+        public String toString() {
+            return tag.toString() +
+                    (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (! (other instanceof TypePathEntry)) {
+                return false;
+            }
+            TypePathEntry tpe = (TypePathEntry) other;
+            return this.tag == tpe.tag && this.arg == tpe.arg;
+        }
+
+        @Override
+        public int hashCode() {
+            return this.tag.hashCode() * 17 + this.arg;
+        }
+    }
+
     public TargetType type = TargetType.UNKNOWN;
 
     // For generic/array types.
-    public List<Integer> location = List.nil();
+    public List<TypePathEntry> location = List.nil();
 
     // Tree position.
     public int pos = -1;
@@ -59,11 +141,13 @@
     // For type parameter and method parameter
     public int parameter_index = Integer.MIN_VALUE;
 
-    // For class extends, implements, and throws classes
+    // For class extends, implements, and throws clauses
     public int type_index = Integer.MIN_VALUE;
 
-    // For wildcards
-    public TypeAnnotationPosition wildcard_position = null;
+    // For exception parameters, index into exception table
+    public int exception_index = Integer.MIN_VALUE;
+
+    public TypeAnnotationPosition() {}
 
     @Override
     public String toString() {
@@ -72,27 +156,27 @@
         sb.append(type);
 
         switch (type) {
-        // type case
-        case TYPECAST:
-        case TYPECAST_GENERIC_OR_ARRAY:
-            // object creation
+        // type cast
+        case CAST:
+        // instanceof
         case INSTANCEOF:
-        case INSTANCEOF_GENERIC_OR_ARRAY:
-            // new expression
+        // new expression
         case NEW:
-        case NEW_GENERIC_OR_ARRAY:
-        case NEW_TYPE_ARGUMENT:
-        case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
             sb.append(", offset = ");
             sb.append(offset);
             break;
-            // local variable
+        // local variable
         case LOCAL_VARIABLE:
-        case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
+        // resource variable
+        case RESOURCE_VARIABLE:
+            if (lvarOffset == null) {
+                sb.append(", lvarOffset is null!");
+                break;
+            }
             sb.append(", {");
             for (int i = 0; i < lvarOffset.length; ++i) {
                 if (i != 0) sb.append("; ");
-                sb.append(", start_pc = ");
+                sb.append("start_pc = ");
                 sb.append(lvarOffset[i]);
                 sb.append(", length = ");
                 sb.append(lvarLength[i]);
@@ -101,73 +185,72 @@
             }
             sb.append("}");
             break;
-            // method receiver
+        // method receiver
         case METHOD_RECEIVER:
             // Do nothing
             break;
-            // type parameters
+        // type parameter
         case CLASS_TYPE_PARAMETER:
         case METHOD_TYPE_PARAMETER:
             sb.append(", param_index = ");
             sb.append(parameter_index);
             break;
-            // type parameters bound
+        // type parameter bound
         case CLASS_TYPE_PARAMETER_BOUND:
-        case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
         case METHOD_TYPE_PARAMETER_BOUND:
-        case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
             sb.append(", param_index = ");
             sb.append(parameter_index);
             sb.append(", bound_index = ");
             sb.append(bound_index);
             break;
-            // wildcard
-        case WILDCARD_BOUND:
-        case WILDCARD_BOUND_GENERIC_OR_ARRAY:
-            sb.append(", wild_card = ");
-            sb.append(wildcard_position);
-            break;
-            // Class extends and implements clauses
+        // class extends or implements clause
         case CLASS_EXTENDS:
-        case CLASS_EXTENDS_GENERIC_OR_ARRAY:
             sb.append(", type_index = ");
             sb.append(type_index);
             break;
-            // throws
+        // throws
         case THROWS:
             sb.append(", type_index = ");
             sb.append(type_index);
             break;
-        case CLASS_LITERAL:
-        case CLASS_LITERAL_GENERIC_OR_ARRAY:
-            sb.append(", offset = ");
-            sb.append(offset);
+        // exception parameter
+        case EXCEPTION_PARAMETER:
+            sb.append(", exception_index = ");
+            sb.append(exception_index);
             break;
-            // method parameter: not specified
-        case METHOD_PARAMETER_GENERIC_OR_ARRAY:
+        // method parameter
+        case METHOD_FORMAL_PARAMETER:
             sb.append(", param_index = ");
             sb.append(parameter_index);
             break;
-            // method type argument: wasn't specified
-        case METHOD_TYPE_ARGUMENT:
-        case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+        // method/constructor/reference type argument
+        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
+        case METHOD_INVOCATION_TYPE_ARGUMENT:
+        case METHOD_REFERENCE_TYPE_ARGUMENT:
             sb.append(", offset = ");
             sb.append(offset);
             sb.append(", type_index = ");
             sb.append(type_index);
             break;
-            // We don't need to worry abut these
-        case METHOD_RETURN_GENERIC_OR_ARRAY:
-        case FIELD_GENERIC_OR_ARRAY:
+        // We don't need to worry about these
+        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;
         default:
-            //                throw new AssertionError("unknown type: " + type);
+            Assert.error("Unknown target type: " + type);
         }
 
         // Append location data for generics/arrays.
-        if (type.hasLocation()) {
+        if (!location.isEmpty()) {
             sb.append(", location = (");
             sb.append(location);
             sb.append(")");
@@ -186,10 +269,33 @@
      * @return true if the target has not been optimized away
      */
     public boolean emitToClassfile() {
-        if (type == TargetType.WILDCARD_BOUND
-            || type == TargetType.WILDCARD_BOUND_GENERIC_OR_ARRAY)
-            return wildcard_position.isValidOffset;
-        else
-            return !type.isLocal() || isValidOffset;
+        return !type.isLocal() || isValidOffset;
+    }
+
+    /**
+     * Decode the binary representation for a type path and set
+     * the {@code location} field.
+     *
+     * @param list The bytecode representation of the type path.
+     */
+    public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
+        ListBuffer<TypePathEntry> loc = ListBuffer.lb();
+        Iterator<Integer> iter = list.iterator();
+        while (iter.hasNext()) {
+            Integer fst = iter.next();
+            Assert.check(iter.hasNext(), "Could not decode type path: " + list);
+            Integer snd = iter.next();
+            loc = loc.append(TypePathEntry.fromBinary(fst, snd));
+        }
+        return loc.toList();
+    }
+
+    public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
+        ListBuffer<Integer> loc = ListBuffer.lb();
+        for (TypePathEntry tpe : locs) {
+            loc = loc.append(tpe.tag.tag);
+            loc = loc.append(tpe.arg);
+        }
+        return loc.toList();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Sat Jan 26 19:24:46 2013 -0800
@@ -0,0 +1,1037 @@
+/*
+ * 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
+ * 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.code;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.type.TypeKind;
+
+import com.sun.tools.javac.code.Attribute;
+import com.sun.tools.javac.code.Attribute.TypeCompound;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.code.Type.AnnotatedType;
+import com.sun.tools.javac.code.Type.ArrayType;
+import com.sun.tools.javac.code.Type.CapturedType;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Type.ErrorType;
+import com.sun.tools.javac.code.Type.ForAll;
+import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.code.Type.PackageType;
+import com.sun.tools.javac.code.Type.TypeVar;
+import com.sun.tools.javac.code.Type.UndetVar;
+import com.sun.tools.javac.code.Type.Visitor;
+import com.sun.tools.javac.code.Type.WildcardType;
+import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
+import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
+import com.sun.tools.javac.code.TypeTag;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.comp.Annotate.Annotator;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCTypeApply;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Names;
+
+/**
+ * Contains operations specific to processing type annotations.
+ * This class has two functions:
+ * separate declaration from type annotations and insert the type
+ * annotations to their types;
+ * and determine the TypeAnnotationPositions for all type annotations.
+ */
+public class TypeAnnotations {
+    // Class cannot be instantiated.
+    private TypeAnnotations() {}
+
+    /**
+     * Separate type annotations from declaration annotations and
+     * determine the correct positions for type annotations.
+     * This version only visits types in signatures and should be
+     * called from MemberEnter.
+     * The method returns the Annotator object that should be added
+     * to the correct Annotate queue for later processing.
+     */
+    public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
+            final Log log, final JCClassDecl tree) {
+        return new Annotator() {
+            @Override
+            public void enterAnnotation() {
+                new TypeAnnotationPositions(syms, names, log, true).scan(tree);
+            }
+        };
+    }
+
+    /**
+     * This version only visits types in bodies, that is, field initializers,
+     * top-level blocks, and method bodies, and should be called from Attr.
+     */
+    public static void organizeTypeAnnotationsBodies(Symtab syms, Names names, Log log, JCClassDecl tree) {
+        new TypeAnnotationPositions(syms, names, log, false).scan(tree);
+    }
+
+    private static class TypeAnnotationPositions extends TreeScanner {
+
+        private enum AnnotationType { DECLARATION, TYPE, BOTH };
+
+        private final Symtab syms;
+        private final Names names;
+        private final Log log;
+        private final boolean sigOnly;
+
+        private TypeAnnotationPositions(Symtab syms, Names names, Log log, boolean sigOnly) {
+            this.syms = syms;
+            this.names = names;
+            this.log = log;
+            this.sigOnly = sigOnly;
+        }
+
+        /*
+         * When traversing the AST we keep the "frames" of visited
+         * trees in order to determine the position of annotations.
+         */
+        private ListBuffer<JCTree> frames = ListBuffer.lb();
+
+        protected void push(JCTree t) { frames = frames.prepend(t); }
+        protected JCTree pop() { return frames.next(); }
+        // could this be frames.elems.tail.head?
+        private JCTree peek2() { return frames.toList().tail.head; }
+
+        @Override
+        public void scan(JCTree tree) {
+            push(tree);
+            super.scan(tree);
+            pop();
+        }
+
+        /**
+         * Separates type annotations from declaration annotations.
+         * This step is needed because in certain locations (where declaration
+         * and type annotations can be mixed, e.g. the type of a field)
+         * we never build an JCAnnotatedType. This step finds these
+         * annotations and marks them as if they were part of the type.
+         */
+        private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym,
+                TypeAnnotationPosition pos) {
+            /*
+            System.out.printf("separateAnnotationsKinds(typetree: %s, type: %s, symbol: %s, pos: %s%n",
+                    typetree, type, sym, pos);
+            */
+            List<Attribute.Compound> annotations = sym.getRawAttributes();
+            ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<Attribute.Compound>();
+            ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
+
+            for (Attribute.Compound a : annotations) {
+                switch (annotationType(a, sym)) {
+                case DECLARATION:
+                    declAnnos.append(a);
+                    break;
+                case BOTH: {
+                    declAnnos.append(a);
+                    Attribute.TypeCompound ta = toTypeCompound(a, pos);
+                    typeAnnos.append(ta);
+                    break;
+                }
+                case TYPE: {
+                    Attribute.TypeCompound ta = toTypeCompound(a, pos);
+                    typeAnnos.append(ta);
+                    break;
+                }
+                }
+            }
+
+            sym.annotations.reset();
+            sym.annotations.setDeclarationAttributes(declAnnos.toList());
+
+            List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList();
+
+            if (type == null) {
+                // When type is null, put the type annotations to the symbol.
+                // This is used for constructor return annotations, for which
+                // no appropriate type exists.
+                sym.annotations.appendUniqueTypes(typeAnnotations);
+                return;
+            }
+
+            // type is non-null and annotations are added to that type
+            type = typeWithAnnotations(typetree, type, typeAnnotations, log);
+
+            if (sym.getKind() == ElementKind.METHOD) {
+                sym.type.asMethodType().restype = type;
+            } else {
+                sym.type = type;
+            }
+
+            sym.annotations.appendUniqueTypes(typeAnnotations);
+            if (sym.getKind() == ElementKind.PARAMETER &&
+                    sym.getQualifiedName().equals(names._this)) {
+                sym.owner.type.asMethodType().recvtype = type;
+                // note that the typeAnnotations will also be added to the owner below.
+            }
+            if (sym.getKind() == ElementKind.PARAMETER ||
+                    sym.getKind() == ElementKind.LOCAL_VARIABLE ||
+                    sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
+                    sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
+                // Make sure all type annotations from the symbol are also
+                // on the owner.
+                sym.owner.annotations.appendUniqueTypes(sym.getTypeAnnotationMirrors());
+            }
+        }
+
+        // This method has a similar purpose as
+        // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)}
+        // We found a type annotation in a declaration annotation position,
+        // for example, on the return type.
+        // 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.
+        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",
+            //         typetree, type, annotations);
+            if (annotations.isEmpty()) {
+                return type;
+            }
+            if (type.hasTag(TypeTag.ARRAY)) {
+                Type toreturn;
+                Type.ArrayType tomodify;
+                Type.ArrayType arType;
+                {
+                    Type touse = type;
+                    if (type.getKind() == TypeKind.ANNOTATED) {
+                        Type.AnnotatedType atype = (Type.AnnotatedType)type;
+                        toreturn = new Type.AnnotatedType(atype.underlyingType);
+                        ((Type.AnnotatedType)toreturn).typeAnnotations = atype.typeAnnotations;
+                        touse = atype.underlyingType;
+                        arType = (Type.ArrayType) touse;
+                        tomodify = new Type.ArrayType(null, arType.tsym);
+                        ((Type.AnnotatedType)toreturn).underlyingType = tomodify;
+                    } else {
+                        arType = (Type.ArrayType) touse;
+                        tomodify = new Type.ArrayType(null, arType.tsym);
+                        toreturn = tomodify;
+                    }
+                }
+                JCArrayTypeTree arTree = arrayTypeTree(typetree);
+
+                ListBuffer<TypePathEntry> depth = ListBuffer.lb();
+                depth = depth.append(TypePathEntry.ARRAY);
+                while (arType.elemtype.hasTag(TypeTag.ARRAY)) {
+                    if (arType.elemtype.getKind() == TypeKind.ANNOTATED) {
+                        Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype;
+                        Type.AnnotatedType newAT = new Type.AnnotatedType(aelemtype.underlyingType);
+                        tomodify.elemtype = newAT;
+                        newAT.typeAnnotations = aelemtype.typeAnnotations;
+                        arType = (Type.ArrayType) aelemtype.underlyingType;
+                        tomodify = new Type.ArrayType(null, arType.tsym);
+                        newAT.underlyingType = tomodify;
+                    } else {
+                        arType = (Type.ArrayType) arType.elemtype;
+                        tomodify.elemtype = new Type.ArrayType(null, arType.tsym);
+                        tomodify = (Type.ArrayType) tomodify.elemtype;
+                    }
+                    arTree = arrayTypeTree(arTree.elemtype);
+                    depth = depth.append(TypePathEntry.ARRAY);
+                }
+                Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log);
+                tomodify.elemtype = arelemType;
+                for (Attribute.TypeCompound a : annotations) {
+                    TypeAnnotationPosition p = a.position;
+                    p.location = p.location.prependList(depth.toList());
+                }
+                return toreturn;
+            } else if (type.hasTag(TypeTag.TYPEVAR)) {
+                // Nothing to do for type variables.
+                return type;
+            } else {
+                Type enclTy = type;
+                Element enclEl = type.asElement();
+                JCTree enclTr = typetree;
+
+                while (enclEl != null &&
+                        enclEl.getKind() != ElementKind.PACKAGE &&
+                        enclTy != null &&
+                        enclTy.getKind() != TypeKind.NONE &&
+                        enclTy.getKind() != TypeKind.ERROR &&
+                        (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT ||
+                         enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE ||
+                         enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) {
+                    // Iterate also over the type tree, not just the type: the type is already
+                    // completely resolved and we cannot distinguish where the annotation
+                    // belongs for a nested type.
+                    if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) {
+                        // only change encl in this case.
+                        enclTy = enclTy.getEnclosingType();
+                        enclEl = enclEl.getEnclosingElement();
+                        enclTr = ((JCFieldAccess)enclTr).getExpression();
+                    } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) {
+                        enclTr = ((JCTypeApply)enclTr).getType();
+                    } else {
+                        // only other option because of while condition
+                        enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType();
+                    }
+                }
+
+                /** We are trying to annotate some enclosing type,
+                 * but nothing more exists.
+                 */
+                if (enclTy != null &&
+                        enclTy.getKind() == TypeKind.NONE &&
+                        (enclTr.getKind() == JCTree.Kind.IDENTIFIER ||
+                         enclTr.getKind() == JCTree.Kind.MEMBER_SELECT ||
+                         enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE ||
+                         enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) {
+                    // TODO: also if it's "java. @A lang.Object", that is,
+                    // if it's on a package?
+                    log.error(enclTr.pos(), "cant.annotate.nested.type", enclTr.toString());
+                    return type;
+                }
+
+                // At this point we have visited the part of the nested
+                // type that is written in the source code.
+                // Now count from here to the actual top-level class to determine
+                // the correct nesting.
+
+                // The genericLocation for the annotation.
+                ListBuffer<TypePathEntry> depth = ListBuffer.lb();
+
+                Type topTy = enclTy;
+                while (enclEl != null &&
+                        enclEl.getKind() != ElementKind.PACKAGE &&
+                        topTy != null &&
+                        topTy.getKind() != TypeKind.NONE &&
+                        topTy.getKind() != TypeKind.ERROR) {
+                    topTy = topTy.getEnclosingType();
+                    enclEl = enclEl.getEnclosingElement();
+
+                    if (topTy != null && topTy.getKind() != TypeKind.NONE) {
+                        // Only count enclosing types.
+                        depth = depth.append(TypePathEntry.INNER_TYPE);
+                    }
+                }
+
+                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());
+                    }
+                }
+
+                Type ret = typeWithAnnotations(type, enclTy, annotations);
+                return ret;
+            }
+        }
+
+        private static JCArrayTypeTree arrayTypeTree(JCTree typetree) {
+            if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) {
+                return (JCArrayTypeTree) typetree;
+            } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) {
+                return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType;
+            } else {
+                Assert.error("Could not determine array type from type tree: " + typetree);
+                return null;
+            }
+        }
+
+        /** Return a copy of the first type that only differs by
+         * inserting the annotations to the left-most/inner-most type
+         * or the type given by stopAt.
+         *
+         * We need the stopAt parameter to know where on a type to
+         * put the annotations.
+         * If we have nested classes Outer > Middle > Inner, and we
+         * have the source type "@A Middle.Inner", we will invoke
+         * this method with type = Outer.Middle.Inner,
+         * stopAt = Middle.Inner, and annotations = @A.
+         *
+         * @param type The type to copy.
+         * @param stopAt The type to stop at.
+         * @param annotations The annotations to insert.
+         * @return A copy of type that contains the annotations.
+         */
+        private static Type typeWithAnnotations(final Type type,
+                final Type stopAt,
+                final List<Attribute.TypeCompound> annotations) {
+            Visitor<Type, List<TypeCompound>> visitor =
+                    new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
+                @Override
+                public Type visitClassType(ClassType t, List<TypeCompound> s) {
+                    // assert that t.constValue() == null?
+                    if (t == stopAt ||
+                        t.getEnclosingType() == Type.noType) {
+                        return new AnnotatedType(s, t);
+                    } else {
+                        ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
+                                t.typarams_field, t.tsym);
+                        ret.all_interfaces_field = t.all_interfaces_field;
+                        ret.allparams_field = t.allparams_field;
+                        ret.interfaces_field = t.interfaces_field;
+                        ret.rank_field = t.rank_field;
+                        ret.supertype_field = t.supertype_field;
+                        return ret;
+                    }
+                }
+
+                @Override
+                public Type visitAnnotatedType(AnnotatedType t, List<TypeCompound> s) {
+                    return new AnnotatedType(t.typeAnnotations, t.underlyingType.accept(this, s));
+                }
+
+                @Override
+                public Type visitWildcardType(WildcardType t, List<TypeCompound> s) {
+                    return new AnnotatedType(s, t);
+                }
+
+                @Override
+                public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
+                    ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym);
+                    return ret;
+                }
+
+                @Override
+                public Type visitMethodType(MethodType t, List<TypeCompound> s) {
+                    // Impossible?
+                    return t;
+                }
+
+                @Override
+                public Type visitPackageType(PackageType t, List<TypeCompound> s) {
+                    // Impossible?
+                    return t;
+                }
+
+                @Override
+                public Type visitTypeVar(TypeVar t, List<TypeCompound> s) {
+                    return new AnnotatedType(s, t);
+                }
+
+                @Override
+                public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
+                    return new AnnotatedType(s, t);
+                }
+
+                @Override
+                public Type visitForAll(ForAll t, List<TypeCompound> s) {
+                    // Impossible?
+                    return t;
+                }
+
+                @Override
+                public Type visitUndetVar(UndetVar t, List<TypeCompound> s) {
+                    // Impossible?
+                    return t;
+                }
+
+                @Override
+                public Type visitErrorType(ErrorType t, List<TypeCompound> s) {
+                    return new AnnotatedType(s, t);
+                }
+
+                @Override
+                public Type visitType(Type t, List<TypeCompound> s) {
+                    // Error?
+                    return t;
+                }
+            };
+
+            return type.accept(visitor, annotations);
+        }
+
+        private static Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) {
+            // It is safe to alias the position.
+            return new Attribute.TypeCompound(a, p);
+        }
+
+        private AnnotationType annotationType(Attribute.Compound a, Symbol s) {
+            Attribute.Compound atTarget =
+                a.type.tsym.attribute(syms.annotationTargetType.tsym);
+            if (atTarget == null) {
+                return inferTargetMetaInfo(a, s);
+            }
+            Attribute atValue = atTarget.member(names.value);
+            if (!(atValue instanceof Attribute.Array)) {
+                Assert.error("annotationType(): bad @Target argument " + atValue +
+                        " (" + atValue.getClass() + ")");
+                return AnnotationType.DECLARATION; // error recovery
+            }
+            Attribute.Array arr = (Attribute.Array) atValue;
+            boolean isDecl = false, isType = false;
+            for (Attribute app : arr.values) {
+                if (!(app instanceof Attribute.Enum)) {
+                    Assert.error("annotationType(): unrecognized Attribute kind " + app +
+                            " (" + app.getClass() + ")");
+                    isDecl = true;
+                    continue;
+                }
+                Attribute.Enum e = (Attribute.Enum) app;
+                if (e.value.name == names.TYPE) {
+                    if (s.kind == Kinds.TYP)
+                        isDecl = true;
+                } else if (e.value.name == names.FIELD) {
+                    if (s.kind == Kinds.VAR &&
+                            s.owner.kind != Kinds.MTH)
+                        isDecl = true;
+                } else if (e.value.name == names.METHOD) {
+                    if (s.kind == Kinds.MTH &&
+                            !s.isConstructor())
+                        isDecl = true;
+                } else if (e.value.name == names.PARAMETER) {
+                    if (s.kind == Kinds.VAR &&
+                            s.owner.kind == Kinds.MTH &&
+                            (s.flags() & Flags.PARAMETER) != 0)
+                        isDecl = true;
+                } else if (e.value.name == names.CONSTRUCTOR) {
+                    if (s.kind == Kinds.MTH &&
+                            s.isConstructor())
+                        isDecl = true;
+                } else if (e.value.name == names.LOCAL_VARIABLE) {
+                    if (s.kind == Kinds.VAR &&
+                            s.owner.kind == Kinds.MTH &&
+                            (s.flags() & Flags.PARAMETER) == 0)
+                        isDecl = true;
+                } else if (e.value.name == names.ANNOTATION_TYPE) {
+                    if (s.kind == Kinds.TYP &&
+                            (s.flags() & Flags.ANNOTATION) != 0)
+                        isDecl = true;
+                } else if (e.value.name == names.PACKAGE) {
+                    if (s.kind == Kinds.PCK)
+                        isDecl = true;
+                } else if (e.value.name == names.TYPE_USE) {
+                    if (s.kind == Kinds.TYP ||
+                            s.kind == Kinds.VAR ||
+                            (s.kind == Kinds.MTH && !s.isConstructor() &&
+                            !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
+                            (s.kind == Kinds.MTH && s.isConstructor()))
+                        isType = true;
+                } else if (e.value.name == names.TYPE_PARAMETER) {
+                    /* Irrelevant in this case */
+                    // TYPE_PARAMETER doesn't aid in distinguishing between
+                    // Type annotations and declaration annotations on an
+                    // Element
+                } else {
+                    Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
+                            " (" + e.value.name.getClass() + ")");
+                    isDecl = true;
+                }
+            }
+            if (isDecl && isType) {
+                return AnnotationType.BOTH;
+            } else if (isType) {
+                return AnnotationType.TYPE;
+            } else {
+                return AnnotationType.DECLARATION;
+            }
+        }
+
+        /** Infer the target annotation kind, if none is give.
+         * We only infer declaration annotations.
+         */
+        private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
+            return AnnotationType.DECLARATION;
+        }
+
+
+        /* This is the beginning of the second part of organizing
+         * type annotations: determine the type annotation positions.
+         */
+
+        private void resolveFrame(JCTree tree, JCTree frame,
+                List<JCTree> path, TypeAnnotationPosition p) {
+            /*
+            System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
+            System.out.println("    Framing tree: " + frame + " kind: " + frame.getKind());
+            */
+            switch (frame.getKind()) {
+                case TYPE_CAST:
+                    p.type = TargetType.CAST;
+                    p.pos = frame.pos;
+                    return;
+
+                case INSTANCE_OF:
+                    p.type = TargetType.INSTANCEOF;
+                    p.pos = frame.pos;
+                    return;
+
+                case NEW_CLASS:
+                    JCNewClass frameNewClass = (JCNewClass)frame;
+                    if (frameNewClass.typeargs.contains(tree)) {
+                        p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
+                        p.type_index = frameNewClass.typeargs.indexOf(tree);
+                    } else {
+                        p.type = TargetType.NEW;
+                    }
+                    p.pos = frame.pos;
+                    return;
+
+                case NEW_ARRAY:
+                    p.type = TargetType.NEW;
+                    p.pos = frame.pos;
+                    return;
+
+                case ANNOTATION_TYPE:
+                case CLASS:
+                case ENUM:
+                case INTERFACE:
+                    p.pos = frame.pos;
+                    if (((JCClassDecl)frame).extending == tree) {
+                        p.type = TargetType.CLASS_EXTENDS;
+                        p.type_index = -1;
+                    } else if (((JCClassDecl)frame).implementing.contains(tree)) {
+                        p.type = TargetType.CLASS_EXTENDS;
+                        p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
+                    } else if (((JCClassDecl)frame).typarams.contains(tree)) {
+                        p.type = TargetType.CLASS_TYPE_PARAMETER;
+                        p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
+                    } else {
+                        Assert.error("Could not determine position of tree " + tree +
+                                " within frame " + frame);
+                    }
+                    return;
+
+                case METHOD: {
+                    JCMethodDecl frameMethod = (JCMethodDecl) frame;
+                    p.pos = frame.pos;
+                    if (frameMethod.thrown.contains(tree)) {
+                        p.type = TargetType.THROWS;
+                        p.type_index = frameMethod.thrown.indexOf(tree);
+                    } else if (frameMethod.restype == tree) {
+                        p.type = TargetType.METHOD_RETURN;
+                    } else if (frameMethod.typarams.contains(tree)) {
+                        p.type = TargetType.METHOD_TYPE_PARAMETER;
+                        p.parameter_index = frameMethod.typarams.indexOf(tree);
+                    } else {
+                        Assert.error("Could not determine position of tree " + tree +
+                                " within frame " + frame);
+                    }
+                    return;
+                }
+
+                case PARAMETERIZED_TYPE: {
+                    if (((JCTypeApply)frame).clazz == tree) {
+                        // generic: RAW; noop
+                    } else if (((JCTypeApply)frame).arguments.contains(tree)) {
+                        JCTypeApply taframe = (JCTypeApply) frame;
+                        int arg = taframe.arguments.indexOf(tree);
+                        p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
+
+                        locateNestedTypes(taframe.type, p);
+                    } else {
+                        Assert.error("Could not determine type argument position of tree " + tree +
+                                " within frame " + frame);
+                    }
+
+                    List<JCTree> newPath = path.tail;
+                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                    return;
+                }
+
+                case ARRAY_TYPE: {
+                    ListBuffer<TypePathEntry> index = ListBuffer.lb();
+                    index = index.append(TypePathEntry.ARRAY);
+                    List<JCTree> newPath = path.tail;
+                    while (true) {
+                        JCTree npHead = newPath.tail.head;
+                        if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) {
+                            newPath = newPath.tail;
+                            index = index.append(TypePathEntry.ARRAY);
+                        } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
+                            newPath = newPath.tail;
+                        } else {
+                            break;
+                        }
+                    }
+                    p.location = p.location.prependList(index.toList());
+                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                    return;
+                }
+
+                case TYPE_PARAMETER:
+                    if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) {
+                        JCClassDecl clazz = (JCClassDecl)path.tail.tail.head;
+                        p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
+                        p.parameter_index = clazz.typarams.indexOf(path.tail.head);
+                        p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
+                        if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
+                            // Account for an implicit Object as bound 0
+                            p.bound_index += 1;
+                        }
+                    } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) {
+                        JCMethodDecl method = (JCMethodDecl)path.tail.tail.head;
+                        p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND;
+                        p.parameter_index = method.typarams.indexOf(path.tail.head);
+                        p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
+                        if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
+                            // Account for an implicit Object as bound 0
+                            p.bound_index += 1;
+                        }
+                    } else {
+                        Assert.error("Could not determine position of tree " + tree +
+                                " within frame " + frame);
+                    }
+                    p.pos = frame.pos;
+                    return;
+
+                case VARIABLE:
+                    VarSymbol v = ((JCVariableDecl)frame).sym;
+                    p.pos = frame.pos;
+                    switch (v.getKind()) {
+                        case LOCAL_VARIABLE:
+                            p.type = TargetType.LOCAL_VARIABLE;
+                            break;
+                        case FIELD:
+                            p.type = TargetType.FIELD;
+                            break;
+                        case PARAMETER:
+                            if (v.getQualifiedName().equals(names._this)) {
+                                // TODO: Intro a separate ElementKind?
+                                p.type = TargetType.METHOD_RECEIVER;
+                            } else {
+                                p.type = TargetType.METHOD_FORMAL_PARAMETER;
+                                p.parameter_index = methodParamIndex(path, frame);
+                            }
+                            break;
+                        case EXCEPTION_PARAMETER:
+                            p.type = TargetType.EXCEPTION_PARAMETER;
+                            break;
+                        case RESOURCE_VARIABLE:
+                            p.type = TargetType.RESOURCE_VARIABLE;
+                            break;
+                        default:
+                            Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
+                    }
+                    return;
+
+                case ANNOTATED_TYPE: {
+                    if (frame == tree) {
+                        // This is only true for the first annotated type we see.
+                        // For any other annotated types along the path, we do
+                        // not care about inner types.
+                        JCAnnotatedType atypetree = (JCAnnotatedType) frame;
+                        final Type utype = atypetree.underlyingType.type;
+                        Symbol tsym = utype.tsym;
+                        if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
+                                utype.getKind().equals(TypeKind.WILDCARD) ||
+                                utype.getKind().equals(TypeKind.ARRAY)) {
+                            // Type parameters, wildcards, and arrays have the declaring
+                            // class/method as enclosing elements.
+                            // There is actually nothing to do for them.
+                        } else {
+                            locateNestedTypes(utype, p);
+                        }
+                    }
+                    List<JCTree> newPath = path.tail;
+                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                    return;
+                }
+
+                case UNION_TYPE: {
+                    // TODO: can we store any information here to help in
+                    // determining the final position?
+                    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)) {
+                        Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation);
+                    }
+                    p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
+                    p.pos = invocation.pos;
+                    p.type_index = invocation.typeargs.indexOf(tree);
+                    return;
+                }
+
+                case EXTENDS_WILDCARD:
+                case SUPER_WILDCARD: {
+                    // Annotations in wildcard bounds
+                    p.location = p.location.prepend(TypePathEntry.WILDCARD);
+                    List<JCTree> newPath = path.tail;
+                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                    return;
+                }
+
+                case MEMBER_SELECT: {
+                    List<JCTree> newPath = path.tail;
+                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                    return;
+                }
+
+                default:
+                    Assert.error("Unresolved frame: " + frame + " of kind: " + frame.getKind() +
+                            "\n    Looking for tree: " + tree);
+                    return;
+            }
+        }
+
+        private static void locateNestedTypes(Type type, TypeAnnotationPosition p) {
+            // The number of "steps" to get from the full type to the
+            // left-most outer type.
+            ListBuffer<TypePathEntry> depth = ListBuffer.lb();
+
+            Type encl = type.getEnclosingType();
+            while (encl != null &&
+                    encl.getKind() != TypeKind.NONE &&
+                    encl.getKind() != TypeKind.ERROR) {
+                depth = depth.append(TypePathEntry.INNER_TYPE);
+                encl = encl.getEnclosingType();
+            }
+            if (depth.nonEmpty()) {
+                p.location = p.location.prependList(depth.toList());
+            }
+        }
+
+        private static int methodParamIndex(List<JCTree> path, JCTree param) {
+            List<JCTree> curr = path;
+            while (curr.head.getTag() != Tag.METHODDEF) {
+                curr = curr.tail;
+            }
+            JCMethodDecl method = (JCMethodDecl)curr.head;
+            return method.params.indexOf(param);
+        }
+
+        // Each class (including enclosed inner classes) is visited separately.
+        // This flag is used to prevent from visiting inner classes.
+        private boolean isInClass = false;
+
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+            if (isInClass)
+                return;
+            isInClass = true;
+            if (sigOnly) {
+                scan(tree.mods);
+                scan(tree.typarams);
+                scan(tree.extending);
+                scan(tree.implementing);
+            }
+            scan(tree.defs);
+        }
+
+        /**
+         * Resolve declaration vs. type annotations in methods and
+         * then determine the positions.
+         */
+        @Override
+        public void visitMethodDef(final JCMethodDecl tree) {
+            if (tree.sym == null) {
+                // Something most be wrong, e.g. a class not found.
+                // Quietly ignore. (See test FailOver15.java)
+                return;
+            }
+            if (sigOnly) {
+                {
+                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                    pos.type = TargetType.METHOD_RETURN;
+                    if (tree.sym.isConstructor()) {
+                        pos.pos = tree.pos;
+                        // Use null to mark that the annotations go with the symbol.
+                        separateAnnotationsKinds(tree, null, tree.sym, pos);
+                    } else {
+                        pos.pos = tree.restype.pos;
+                        separateAnnotationsKinds(tree.restype, tree.sym.type.getReturnType(),
+                                tree.sym, pos);
+                    }
+                }
+                if (tree.recvparam != null && tree.recvparam.sym != null) {
+                    // TODO: make sure there are no declaration annotations.
+                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                    pos.type = TargetType.METHOD_RECEIVER;
+                    pos.pos = tree.recvparam.vartype.pos;
+                    separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type,
+                            tree.recvparam.sym, pos);
+                }
+                int i = 0;
+                for (JCVariableDecl param : tree.params) {
+                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                    pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+                    pos.parameter_index = i;
+                    pos.pos = param.vartype.pos;
+                    separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+                    ++i;
+                }
+            }
+
+            push(tree);
+            // super.visitMethodDef(tree);
+            if (sigOnly) {
+                scan(tree.mods);
+                scan(tree.restype);
+                scan(tree.typarams);
+                scan(tree.recvparam);
+                scan(tree.params);
+                scan(tree.thrown);
+            } else {
+                scan(tree.defaultValue);
+                scan(tree.body);
+            }
+            pop();
+        }
+
+        /**
+         * Resolve declaration vs. type annotations in variable declarations and
+         * then determine the positions.
+         */
+        @Override
+        public void visitVarDef(final JCVariableDecl tree) {
+            if (tree.sym == null) {
+                // Something is wrong already. Quietly ignore.
+            } else if (tree.sym.getKind() == ElementKind.FIELD) {
+                if (sigOnly) {
+                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                    pos.type = TargetType.FIELD;
+                    pos.pos = tree.pos;
+                    separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+                }
+            } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) {
+                TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                pos.type = TargetType.LOCAL_VARIABLE;
+                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;
+                separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+            } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
+                TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                pos.type = TargetType.RESOURCE_VARIABLE;
+                pos.pos = tree.pos;
+                separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
+            } else {
+                // There is nothing else in a variable declaration that needs separation.
+                // System.out.println("We found a: " + tree);
+            }
+
+            push(tree);
+            // super.visitVarDef(tree);
+            scan(tree.mods);
+            scan(tree.vartype);
+            if (!sigOnly) {
+                scan(tree.init);
+            }
+            pop();
+        }
+
+        @Override
+        public void visitBlock(JCBlock tree) {
+            // Do not descend into top-level blocks when only interested
+            // in the signature.
+            if (!sigOnly) {
+                scan(tree.stats);
+            }
+        }
+
+        @Override
+        public void visitAnnotatedType(JCAnnotatedType tree) {
+            push(tree);
+            findPosition(tree, tree, tree.annotations);
+            pop();
+            super.visitAnnotatedType(tree);
+        }
+
+        @Override
+        public void visitTypeParameter(JCTypeParameter tree) {
+            findPosition(tree, peek2(), tree.annotations);
+            super.visitTypeParameter(tree);
+        }
+
+        @Override
+        public void visitNewArray(JCNewArray tree) {
+            findPosition(tree, tree, tree.annotations);
+            int dimAnnosCount = tree.dimAnnotations.size();
+            ListBuffer<TypePathEntry> depth = ListBuffer.lb();
+
+            // handle annotations associated with dimensions
+            for (int i = 0; i < dimAnnosCount; ++i) {
+                TypeAnnotationPosition p = new TypeAnnotationPosition();
+                p.pos = tree.pos;
+                p.type = TargetType.NEW;
+                if (i != 0) {
+                    depth = depth.append(TypePathEntry.ARRAY);
+                    p.location = p.location.appendList(depth.toList());
+                }
+
+                setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
+            }
+
+            // handle "free" annotations
+            // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
+            // TODO: is depth.size == i here?
+            JCExpression elemType = tree.elemtype;
+            while (elemType != null) {
+                if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
+                    JCAnnotatedType at = (JCAnnotatedType)elemType;
+                    TypeAnnotationPosition p = new TypeAnnotationPosition();
+                    p.type = TargetType.NEW;
+                    p.pos = tree.pos;
+                    p.location = p.location.appendList(depth.toList());
+                    setTypeAnnotationPos(at.annotations, p);
+                    elemType = at.underlyingType;
+                } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
+                    depth = depth.append(TypePathEntry.ARRAY);
+                    elemType = ((JCArrayTypeTree)elemType).elemtype;
+                } else {
+                    break;
+                }
+            }
+            scan(tree.elems);
+        }
+
+        private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) {
+            if (!annotations.isEmpty()) {
+                /*
+                System.out.println("Finding pos for: " + annotations);
+                System.out.println("    tree: " + tree);
+                System.out.println("    frame: " + frame);
+                */
+                TypeAnnotationPosition p = new TypeAnnotationPosition();
+                resolveFrame(tree, frame, frames.toList(), p);
+                setTypeAnnotationPos(annotations, p);
+            }
+        }
+
+        private static void setTypeAnnotationPos(List<JCAnnotation> annotations,
+                TypeAnnotationPosition position) {
+            for (JCAnnotation anno : annotations) {
+                ((Attribute.TypeCompound) anno.attribute).position = position;
+            }
+        }
+    }
+}
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,13 +34,14 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 
+import javax.lang.model.type.TypeKind;
+
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
 import com.sun.tools.javac.comp.Check;
 import com.sun.tools.javac.jvm.ClassReader;
 import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Scope.*;
@@ -354,8 +355,29 @@
                 return descSym;
             }
 
-            public Type getType(Type origin) {
-                return memberType(origin, descSym);
+            public Type getType(Type site) {
+                if (capture(site) != site) {
+                    Type formalInterface = site.tsym.type;
+                    ListBuffer<Type> typeargs = ListBuffer.lb();
+                    List<Type> actualTypeargs = site.getTypeArguments();
+                    //simply replace the wildcards with its bound
+                    for (Type t : formalInterface.getTypeArguments()) {
+                        if (actualTypeargs.head.hasTag(WILDCARD)) {
+                            WildcardType wt = (WildcardType)actualTypeargs.head;
+                            typeargs.append(wt.type);
+                        } else {
+                            typeargs.append(actualTypeargs.head);
+                        }
+                        actualTypeargs = actualTypeargs.tail;
+                    }
+                    site = subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList());
+                    if (!chk.checkValidGenericType(site)) {
+                        //if the inferred functional interface type is not well-formed,
+                        //or if it's not a subtype of the original target, issue an error
+                        throw failure(diags.fragment("no.suitable.functional.intf.inst", site));
+                    }
+                }
+                return memberType(site, descSym);
             }
         }
 
@@ -392,9 +414,9 @@
          * Compute the function descriptor associated with a given functional interface
          */
         public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError {
-            if (!origin.isInterface()) {
+            if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) {
                 //t must be an interface
-                throw failure("not.a.functional.intf");
+                throw failure("not.a.functional.intf", origin);
             }
 
             final ListBuffer<Symbol> abstracts = ListBuffer.lb();
@@ -406,13 +428,13 @@
                     abstracts.append(sym);
                 } else {
                     //the target method(s) should be the only abstract members of t
-                    throw failure("not.a.functional.intf.1",
+                    throw failure("not.a.functional.intf.1",  origin,
                             diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin));
                 }
             }
             if (abstracts.isEmpty()) {
                 //t must define a suitable non-generic method
-                throw failure("not.a.functional.intf.1",
+                throw failure("not.a.functional.intf.1", origin,
                             diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
             } else if (abstracts.size() == 1) {
                 return new FunctionDescriptor(abstracts.first());
@@ -553,6 +575,15 @@
             return false;
         }
     }
+
+    public boolean isFunctionalInterface(Type site) {
+        try {
+            findDescriptorType(site);
+            return true;
+        } catch (FunctionDescriptorLookupError ex) {
+            return false;
+        }
+    }
     // </editor-fold>
 
    /**
@@ -654,6 +685,8 @@
     //where
         private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
             if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
+                t = t.unannotatedType();
+                s = s.unannotatedType();
                 if (((ArrayType)t).elemtype.isPrimitive()) {
                     return isSameType(elemtype(t), elemtype(s));
                 } else {
@@ -679,7 +712,10 @@
         }
 
         private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
-            if (t.tag != ARRAY || isReifiable(t)) return;
+            if (t.tag != ARRAY || isReifiable(t))
+                return;
+            t = t.unannotatedType();
+            s = s.unannotatedType();
             ArrayType from = (ArrayType)t;
             boolean shouldWarn = false;
             switch (s.tag) {
@@ -712,6 +748,12 @@
         if (t == s)
             return true;
 
+        t = t.unannotatedType();
+        s = s.unannotatedType();
+
+        if (t == s)
+            return true;
+
         if (s.isPartial())
             return isSuperType(s, t);
 
@@ -1653,6 +1695,7 @@
         case WILDCARD:
             return elemtype(upperBound(t));
         case ARRAY:
+            t = t.unannotatedType();
             return ((ArrayType)t).elemtype;
         case FORALL:
             return elemtype(((ForAll)t).qtype);
@@ -1981,6 +2024,11 @@
             public Type visitErrorType(ErrorType t, Boolean recurse) {
                 return t;
             }
+
+            @Override
+            public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
+                return new AnnotatedType(t.typeAnnotations, erasure(t.underlyingType, recurse));
+            }
         };
 
     private Mapping erasureFun = new Mapping ("erasure") {
@@ -2923,6 +2971,7 @@
      * graph. Undefined for all but reference types.
      */
     public int rank(Type t) {
+        t = t.unannotatedType();
         switch(t.tag) {
         case CLASS: {
             ClassType cls = (ClassType)t;
@@ -3624,6 +3673,7 @@
                 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
             }
         }
+        t = t.unannotatedType();
         ClassType cls = (ClassType)t;
         if (cls.isRaw() || !cls.isParameterized())
             return cls;
@@ -4142,6 +4192,8 @@
         public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
         public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
         public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
+        // Pretend annotations don't exist
+        public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); }
     }
 
     /**
--- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.comp;
 
 import java.util.Map;
+
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.code.*;
@@ -87,20 +88,30 @@
     private int enterCount = 0;
 
     ListBuffer<Annotator> q = new ListBuffer<Annotator>();
+    ListBuffer<Annotator> typesQ = new ListBuffer<Annotator>();
     ListBuffer<Annotator> repeatedQ = new ListBuffer<Annotator>();
+    ListBuffer<Annotator> afterRepeatedQ = new ListBuffer<Annotator>();
+
+    public void earlier(Annotator a) {
+        q.prepend(a);
+    }
 
     public void normal(Annotator a) {
         q.append(a);
     }
 
-    public void earlier(Annotator a) {
-        q.prepend(a);
+    public void typeAnnotation(Annotator a) {
+        typesQ.append(a);
     }
 
     public void repeated(Annotator a) {
         repeatedQ.append(a);
     }
 
+    public void afterRepeated(Annotator a) {
+        afterRepeatedQ.append(a);
+    }
+
     /** Called when the Enter phase starts. */
     public void enterStart() {
         enterCount++;
@@ -116,12 +127,18 @@
         if (enterCount != 0) return;
         enterCount++;
         try {
-            while (q.nonEmpty())
+            while (q.nonEmpty()) {
                 q.next().enterAnnotation();
-
+            }
+            while (typesQ.nonEmpty()) {
+                typesQ.next().enterAnnotation();
+            }
             while (repeatedQ.nonEmpty()) {
                 repeatedQ.next().enterAnnotation();
             }
+            while (afterRepeatedQ.nonEmpty()) {
+                afterRepeatedQ.next().enterAnnotation();
+            }
         } finally {
             enterCount--;
         }
@@ -141,16 +158,18 @@
      * This context contains all the information needed to synthesize new
      * annotations trees by the completer for repeating annotations.
      */
-    public class AnnotateRepeatedContext {
+    public class AnnotateRepeatedContext<T extends Attribute.Compound> {
         public final Env<AttrContext> env;
-        public final Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated;
-        public final Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos;
+        public final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated;
+        public final Map<T, JCDiagnostic.DiagnosticPosition> pos;
         public final Log log;
+        public final boolean isTypeCompound;
 
         public AnnotateRepeatedContext(Env<AttrContext> env,
-                                       Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated,
-                                       Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos,
-                                       Log log) {
+                                       Map<Symbol.TypeSymbol, ListBuffer<T>> annotated,
+                                       Map<T, JCDiagnostic.DiagnosticPosition> pos,
+                                       Log log,
+                                       boolean isTypeCompound) {
             Assert.checkNonNull(env);
             Assert.checkNonNull(annotated);
             Assert.checkNonNull(pos);
@@ -160,6 +179,7 @@
             this.annotated = annotated;
             this.pos = pos;
             this.log = log;
+            this.isTypeCompound = isTypeCompound;
         }
 
         /**
@@ -170,7 +190,7 @@
          * @param repeatingAnnotations a List of repeating annotations
          * @return a new Attribute.Compound that is the container for the repeatingAnnotations
          */
-        public Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> repeatingAnnotations, Symbol sym) {
+        public T processRepeatedAnnotations(List<T> repeatingAnnotations, Symbol sym) {
             return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this, sym);
         }
 
@@ -246,7 +266,12 @@
                            ((MethodSymbol)method, value));
             t.type = result;
         }
-        return new Attribute.Compound(a.type, buf.toList());
+        // TODO: this should be a TypeCompound if "a" is a JCTypeAnnotation.
+        // However, how do we find the correct position?
+        Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
+        // TODO: is this something we want? Who would use it?
+        // a.attribute = ac;
+        return ac;
     }
 
     Attribute enterAttributeValue(Type expected,
@@ -329,6 +354,15 @@
         return new Attribute.Error(attr.attribExpr(tree, env, expected));
     }
 
+    Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
+            Type expected,
+            Env<AttrContext> env) {
+        Attribute.Compound c = enterAnnotation(a, expected, env);
+        Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, new TypeAnnotationPosition());
+        a.attribute = tc;
+        return tc;
+    }
+
     /* *********************************
      * Support for repeating annotations
      ***********************************/
@@ -337,10 +371,10 @@
      * synthesized container annotation or null IFF all repeating
      * annotation are invalid.  This method reports errors/warnings.
      */
-    private Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> annotations,
-                                                          AnnotateRepeatedContext ctx,
-                                                          Symbol on) {
-        Attribute.Compound firstOccurrence = annotations.head;
+    private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
+            AnnotateRepeatedContext<T> ctx,
+            Symbol on) {
+        T firstOccurrence = annotations.head;
         List<Attribute> repeated = List.nil();
         Type origAnnoType = null;
         Type arrayOfOrigAnnoType = null;
@@ -350,16 +384,16 @@
         Assert.check(!annotations.isEmpty() &&
                      !annotations.tail.isEmpty()); // i.e. size() > 1
 
-        for (List<Attribute.Compound> al = annotations;
+        for (List<T> al = annotations;
              !al.isEmpty();
              al = al.tail)
         {
-            Attribute.Compound currentAnno = al.head;
+            T currentAnno = al.head;
 
             origAnnoType = currentAnno.type;
             if (arrayOfOrigAnnoType == null) {
                 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
-}
+            }
 
             Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno));
             if (currentContainerType == null) {
@@ -383,25 +417,46 @@
 
         if (!repeated.isEmpty()) {
             repeated = repeated.reverse();
-            JCAnnotation annoTree;
             TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
             Pair<MethodSymbol, Attribute> p =
                     new Pair<MethodSymbol, Attribute>(containerValueSymbol,
                                                       new Attribute.Array(arrayOfOrigAnnoType, repeated));
-            annoTree = m.Annotation(new Attribute.Compound(targetContainerType,
-                    List.of(p)));
+            if (ctx.isTypeCompound) {
+                /* TODO: the following code would be cleaner:
+                Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
+                        ((Attribute.TypeCompound)annotations.head).position);
+                JCTypeAnnotation annoTree = m.TypeAnnotation(at);
+                at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env);
+                */
+                // However, we directly construct the TypeCompound to keep the
+                // direct relation to the contained TypeCompounds.
+                Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
+                        ((Attribute.TypeCompound)annotations.head).position);
 
-            if (!chk.annotationApplicable(annoTree, on))
-                log.error(annoTree.pos(), "invalid.containedby.annotation.incompatible.target", targetContainerType, origAnnoType);
+                // TODO: annotation applicability checks from below?
 
-            if (!chk.validateAnnotationDeferErrors(annoTree))
-                log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
+                at.setSynthesized(true);
 
-            Attribute.Compound c = enterAnnotation(annoTree,
-                                                   targetContainerType,
-                                                   ctx.env);
-            c.setSynthesized(true);
-            return c;
+                @SuppressWarnings("unchecked")
+                T x = (T) at;
+                return x;
+            } else {
+                Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));
+                JCAnnotation annoTree = m.Annotation(c);
+
+                if (!chk.annotationApplicable(annoTree, on))
+                    log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
+
+                if (!chk.validateAnnotationDeferErrors(annoTree))
+                    log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
+
+                c = enterAnnotation(annoTree, targetContainerType, ctx.env);
+                c.setSynthesized(true);
+
+                @SuppressWarnings("unchecked")
+                T x = (T) c;
+                return x;
+            }
         } else {
             return null; // errors should have been reported elsewhere
         }
@@ -414,11 +469,11 @@
         Type origAnnoType = currentAnno.type;
         TypeSymbol origAnnoDecl = origAnnoType.tsym;
 
-        // Fetch the ContainedBy annotation from the current
+        // Fetch the Repeatable annotation from the current
         // annotation's declaration, or null if it has none
-        Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym);
-        if (ca == null) { // has no ContainedBy annotation
-            log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.containedByType);
+        Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym);
+        if (ca == null) { // has no Repeatable annotation
+            log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
             return null;
         }
 
@@ -440,23 +495,23 @@
             DiagnosticPosition pos,
             TypeSymbol annoDecl)
     {
-        // The next three checks check that the ContainedBy annotation
+        // The next three checks check that the Repeatable annotation
         // on the declaration of the annotation type that is repeating is
         // valid.
 
-        // ContainedBy must have at least one element
+        // Repeatable must have at least one element
         if (ca.values.isEmpty()) {
-            log.error(pos, "invalid.containedby.annotation", annoDecl);
+            log.error(pos, "invalid.repeatable.annotation", annoDecl);
             return null;
         }
         Pair<MethodSymbol,Attribute> p = ca.values.head;
         Name name = p.fst.name;
         if (name != names.value) { // should contain only one element, named "value"
-            log.error(pos, "invalid.containedby.annotation", annoDecl);
+            log.error(pos, "invalid.repeatable.annotation", annoDecl);
             return null;
         }
         if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
-            log.error(pos, "invalid.containedby.annotation", annoDecl);
+            log.error(pos, "invalid.repeatable.annotation", annoDecl);
             return null;
         }
 
@@ -491,13 +546,13 @@
         }
         if (error) {
             log.error(pos,
-                      "invalid.containedby.annotation.multiple.values",
+                      "invalid.repeatable.annotation.multiple.values",
                       targetContainerType,
                       nr_value_elems);
             return null;
         } else if (nr_value_elems == 0) {
             log.error(pos,
-                      "invalid.containedby.annotation.no.value",
+                      "invalid.repeatable.annotation.no.value",
                       targetContainerType);
             return null;
         }
@@ -506,7 +561,7 @@
         // probably "impossible" to fail this
         if (containerValueSymbol.kind != Kinds.MTH) {
             log.error(pos,
-                      "invalid.containedby.annotation.invalid.value",
+                      "invalid.repeatable.annotation.invalid.value",
                       targetContainerType);
             fatalError = true;
         }
@@ -518,7 +573,7 @@
         if (!(types.isArray(valueRetType) &&
               types.isSameType(expectedType, valueRetType))) {
             log.error(pos,
-                      "invalid.containedby.annotation.value.return",
+                      "invalid.repeatable.annotation.value.return",
                       targetContainerType,
                       valueRetType,
                       expectedType);
@@ -528,10 +583,7 @@
             fatalError = true;
         }
 
-        // Explicitly no check for/validity of @ContainerFor. That is
-        // done on declaration of the container, and at reflect time.
-
-        // The rest of the conditions for a valid containing annotation are made
+        // The conditions for a valid containing annotation are made
         // in Check.validateRepeatedAnnotaton();
 
         return fatalError ? null : containerValueSymbol;
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,9 @@
 package com.sun.tools.javac.comp;
 
 import java.util.*;
-import java.util.Set;
 
 import javax.lang.model.element.ElementKind;
+import javax.lang.model.type.TypeKind;
 import javax.tools.JavaFileObject;
 
 import com.sun.source.tree.IdentifierTree;
@@ -45,9 +45,9 @@
 import com.sun.tools.javac.comp.Infer.InferenceContext;
 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener;
 import com.sun.tools.javac.jvm.*;
-import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
@@ -879,6 +879,7 @@
             deferredLintHandler.flush(tree.pos());
             chk.checkDeprecatedAnnotation(tree.pos(), m);
 
+
             // Create a new environment with local scope
             // for attributing the method.
             Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
@@ -922,6 +923,21 @@
             // Check that result type is well-formed.
             chk.validate(tree.restype, localEnv);
 
+            // Check that receiver type is well-formed.
+            if (tree.recvparam != null) {
+                // Use a new environment to check the receiver parameter.
+                // Otherwise I get "might not have been initialized" errors.
+                // Is there a better way?
+                Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
+                attribType(tree.recvparam, newEnv);
+                chk.validate(tree.recvparam, newEnv);
+                if (!(tree.recvparam.type == m.owner.type || types.isSameType(tree.recvparam.type, m.owner.type))) {
+                    // The == covers the common non-generic case, but for generic classes we need isSameType;
+                    // note that equals didn't work.
+                    log.error(tree.recvparam.pos(), "incorrect.receiver.type");
+                }
+            }
+
             // annotation method checks
             if ((owner.flags() & ANNOTATION) != 0) {
                 // annotation method cannot have throws clause
@@ -953,8 +969,7 @@
                 // Empty bodies are only allowed for
                 // abstract, native, or interface methods, or for methods
                 // in a retrofit signature class.
-                if (isDefaultMethod || ((owner.flags() & INTERFACE) == 0 &&
-                    (tree.mods.flags & (ABSTRACT | NATIVE)) == 0) &&
+                if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
                     !relax)
                     log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
                 if (tree.defaultValue != null) {
@@ -996,9 +1011,14 @@
                     }
                 }
 
+                // Attribute all type annotations in the body
+                memberEnter.typeAnnotate(tree.body, localEnv, m);
+                annotate.flush();
+
                 // Attribute method body.
                 attribStat(tree.body, localEnv);
             }
+
             localEnv.info.scope.leave();
             result = tree.type = m.type;
             chk.validateAnnotations(tree.mods.annotations, m);
@@ -1019,6 +1039,12 @@
                 memberEnter.memberEnter(tree, env);
                 annotate.flush();
             }
+        } else {
+            if (tree.init != null) {
+                // Field initializer expression need to be entered.
+                memberEnter.typeAnnotate(tree.init, env, tree.sym);
+                annotate.flush();
+            }
         }
 
         VarSymbol v = tree.sym;
@@ -1076,6 +1102,11 @@
                 new MethodSymbol(tree.flags | BLOCK, names.empty, null,
                                  env.info.scope.owner);
             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
+
+            // Attribute all type annotations in the block
+            memberEnter.typeAnnotate(tree, localEnv, localEnv.info.scope.owner);
+            annotate.flush();
+
             attribStats(tree.stats, localEnv);
         } else {
             // Create a new local environment with a local scope.
@@ -1376,18 +1407,19 @@
     public void visitConditional(JCConditional tree) {
         Type condtype = attribExpr(tree.cond, env, syms.booleanType);
 
-        boolean standaloneConditional = !allowPoly ||
+        tree.polyKind = (!allowPoly ||
                 pt().hasTag(NONE) && pt() != Type.recoveryType ||
-                isBooleanOrNumeric(env, tree);
-
-        if (!standaloneConditional && resultInfo.pt.hasTag(VOID)) {
+                isBooleanOrNumeric(env, tree)) ?
+                PolyKind.STANDALONE : PolyKind.POLY;
+
+        if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
             //cannot get here (i.e. it means we are returning from void method - which is already an error)
             resultInfo.checkContext.report(tree, diags.fragment("conditional.target.cant.be.void"));
             result = tree.type = types.createErrorType(resultInfo.pt);
             return;
         }
 
-        ResultInfo condInfo = standaloneConditional ?
+        ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
                 unknownExprInfo :
                 resultInfo.dup(new Check.NestedCheckContext(resultInfo.checkContext) {
                     //this will use enclosing check context to check compatibility of
@@ -1402,7 +1434,7 @@
         Type truetype = attribTree(tree.truepart, env, condInfo);
         Type falsetype = attribTree(tree.falsepart, env, condInfo);
 
-        Type owntype = standaloneConditional ? condType(tree, truetype, falsetype) : pt();
+        Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(tree, truetype, falsetype) : pt();
         if (condtype.constValue() != null &&
                 truetype.constValue() != null &&
                 falsetype.constValue() != null &&
@@ -1424,12 +1456,30 @@
                     JCConditional condTree = (JCConditional)tree;
                     return isBooleanOrNumeric(env, condTree.truepart) &&
                             isBooleanOrNumeric(env, condTree.falsepart);
+                case APPLY:
+                    JCMethodInvocation speculativeMethodTree =
+                            (JCMethodInvocation)deferredAttr.attribSpeculative(tree, env, unknownExprInfo);
+                    Type owntype = TreeInfo.symbol(speculativeMethodTree.meth).type.getReturnType();
+                    return types.unboxedTypeOrType(owntype).isPrimitive();
+                case NEWCLASS:
+                    JCExpression className =
+                            removeClassParams.translate(((JCNewClass)tree).clazz);
+                    JCExpression speculativeNewClassTree =
+                            (JCExpression)deferredAttr.attribSpeculative(className, env, unknownTypeInfo);
+                    return types.unboxedTypeOrType(speculativeNewClassTree.type).isPrimitive();
                 default:
                     Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo).type;
                     speculativeType = types.unboxedTypeOrType(speculativeType);
                     return speculativeType.isPrimitive();
             }
         }
+        //where
+            TreeTranslator removeClassParams = new TreeTranslator() {
+                @Override
+                public void visitTypeApply(JCTypeApply tree) {
+                    result = translate(tree.clazz);
+                }
+            };
 
         /** Compute the type of a conditional expression, after
          *  checking that it exists.  See JLS 15.25. Does not take into
@@ -1828,10 +1878,24 @@
         // If enclosing class is given, attribute it, and
         // complete class name to be fully qualified
         JCExpression clazz = tree.clazz; // Class field following new
-        JCExpression clazzid =          // Identifier in class field
-            (clazz.hasTag(TYPEAPPLY))
-            ? ((JCTypeApply) clazz).clazz
-            : clazz;
+        JCExpression clazzid;            // Identifier in class field
+        JCAnnotatedType annoclazzid;     // Annotated type enclosing clazzid
+        annoclazzid = null;
+
+        if (clazz.hasTag(TYPEAPPLY)) {
+            clazzid = ((JCTypeApply) clazz).clazz;
+            if (clazzid.hasTag(ANNOTATED_TYPE)) {
+                annoclazzid = (JCAnnotatedType) clazzid;
+                clazzid = annoclazzid.underlyingType;
+            }
+        } else {
+            if (clazz.hasTag(ANNOTATED_TYPE)) {
+                annoclazzid = (JCAnnotatedType) clazz;
+                clazzid = annoclazzid.underlyingType;
+            } else {
+                clazzid = clazz;
+            }
+        }
 
         JCExpression clazzid1 = clazzid; // The same in fully qualified form
 
@@ -1846,14 +1910,30 @@
             // yields a clazz T.C.
             Type encltype = chk.checkRefType(tree.encl.pos(),
                                              attribExpr(tree.encl, env));
+            // TODO 308: in <expr>.new C, do we also want to add the type annotations
+            // from expr to the combined type, or not? Yes, do this.
             clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
                                                  ((JCIdent) clazzid).name);
-            if (clazz.hasTag(TYPEAPPLY))
-                clazz = make.at(tree.pos).
+
+            if (clazz.hasTag(ANNOTATED_TYPE)) {
+                JCAnnotatedType annoType = (JCAnnotatedType) clazz;
+                List<JCAnnotation> annos = annoType.annotations;
+
+                if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
+                    clazzid1 = make.at(tree.pos).
+                        TypeApply(clazzid1,
+                                  ((JCTypeApply) clazz).arguments);
+                }
+
+                clazzid1 = make.at(tree.pos).
+                    AnnotatedType(annos, clazzid1);
+            } else if (clazz.hasTag(TYPEAPPLY)) {
+                clazzid1 = make.at(tree.pos).
                     TypeApply(clazzid1,
                               ((JCTypeApply) clazz).arguments);
-            else
-                clazz = clazzid1;
+            }
+
+            clazz = clazzid1;
         }
 
         // Attribute clazz expression and store
@@ -1870,6 +1950,9 @@
             tree.clazz.type = clazztype;
             TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
             clazzid.type = ((JCIdent) clazzid).sym.type;
+            if (annoclazzid != null) {
+                annoclazzid.type = clazzid.type;
+            }
             if (!clazztype.isErroneous()) {
                 if (cdef != null && clazztype.tsym.isInterface()) {
                     log.error(tree.encl.pos(), "anon.class.impl.intf.no.qual.for.new");
@@ -2173,17 +2256,18 @@
         boolean needsRecovery =
                 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
         try {
+            Type target = pt();
             List<Type> explicitParamTypes = null;
-            if (TreeInfo.isExplicitLambda(that)) {
+            if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
                 //attribute lambda parameters
                 attribStats(that.params, localEnv);
                 explicitParamTypes = TreeInfo.types(that.params);
+                target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext);
             }
 
-            Type target;
             Type lambdaType;
             if (pt() != Type.recoveryType) {
-                target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), explicitParamTypes, resultInfo.checkContext);
+                target = checkIntersectionTarget(that, target, resultInfo.checkContext);
                 lambdaType = types.findDescriptorType(target);
                 chk.checkFunctionalInterface(that, target);
             } else {
@@ -2191,6 +2275,8 @@
                 lambdaType = fallbackDescriptorType(that);
             }
 
+            setFunctionalInfo(that, pt(), lambdaType, resultInfo.checkContext.inferenceContext());
+
             if (lambdaType.hasTag(FORALL)) {
                 //lambda expression target desc cannot be a generic method
                 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
@@ -2199,7 +2285,7 @@
                 return;
             }
 
-            if (!TreeInfo.isExplicitLambda(that)) {
+            if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
                 //add param type info in the AST
                 List<Type> actuals = lambdaType.getParameterTypes();
                 List<JCVariableDecl> params = that.params;
@@ -2282,8 +2368,7 @@
         }
     }
 
-    private Type checkIntersectionTarget(DiagnosticPosition pos, ResultInfo resultInfo) {
-        Type pt = resultInfo.pt;
+    private Type checkIntersectionTarget(DiagnosticPosition pos, Type pt, CheckContext checkContext) {
         if (pt != Type.recoveryType && pt.isCompound()) {
             IntersectionClassType ict = (IntersectionClassType)pt;
             List<Type> bounds = ict.allInterfaces ?
@@ -2292,7 +2377,7 @@
             types.findDescriptorType(bounds.head); //propagate exception outwards!
             for (Type bound : bounds.tail) {
                 if (!types.isMarkerInterface(bound)) {
-                    resultInfo.checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
+                    checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
                 }
             }
             //for now (translation doesn't support intersection types)
@@ -2355,9 +2440,9 @@
             @Override
             public boolean compatible(Type found, Type req, Warner warn) {
                 //return type must be compatible in both current context and assignment context
-                return types.isAssignable(found, inferenceContext().asFree(req, types), warn) &&
-                        super.compatible(found, req, warn);
+                return chk.basicHandler.compatible(found, inferenceContext().asFree(req, types), warn);
             }
+
             @Override
             public void report(DiagnosticPosition pos, JCDiagnostic details) {
                 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details));
@@ -2473,7 +2558,7 @@
             Type target;
             Type desc;
             if (pt() != Type.recoveryType) {
-                target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), null, resultInfo.checkContext);
+                target = checkIntersectionTarget(that, pt(), resultInfo.checkContext);
                 desc = types.findDescriptorType(target);
                 chk.checkFunctionalInterface(that, target);
             } else {
@@ -2481,12 +2566,11 @@
                 desc = fallbackDescriptorType(that);
             }
 
+            setFunctionalInfo(that, pt(), desc, resultInfo.checkContext.inferenceContext());
             List<Type> argtypes = desc.getParameterTypes();
 
-            boolean allowBoxing =
-                    resultInfo.checkContext.deferredAttrContext().phase.isBoxingRequired();
             Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = rs.resolveMemberReference(that.pos(), localEnv, that,
-                    that.expr.type, that.name, argtypes, typeargtypes, allowBoxing);
+                    that.expr.type, that.name, argtypes, typeargtypes, true);
 
             Symbol refSym = refResult.fst;
             Resolve.ReferenceLookupHelper lookupHelper = refResult.snd;
@@ -2635,6 +2719,34 @@
         }
     }
 
+    /**
+     * Set functional type info on the underlying AST. Note: as the target descriptor
+     * might contain inference variables, we might need to register an hook in the
+     * current inference context.
+     */
+    private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, final Type descriptorType, InferenceContext inferenceContext) {
+        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);
+                }
+            });
+        } else {
+            ListBuffer<TypeSymbol> targets = ListBuffer.lb();
+            if (pt.hasTag(CLASS)) {
+                if (pt.isCompound()) {
+                    for (Type t : ((IntersectionClassType)pt()).interfaces_field) {
+                        targets.append(t.tsym);
+                    }
+                } else {
+                    targets.append(pt.tsym);
+                }
+            }
+            fExpr.targets = targets.toList();
+            fExpr.descriptorType = descriptorType;
+        }
+    }
+
     public void visitParens(JCParens tree) {
         Type owntype = attribTree(tree.expr, env, resultInfo);
         result = check(tree, owntype, pkind(), resultInfo);
@@ -3207,8 +3319,18 @@
                     // Tree<Point>.Visitor.
                     else if (ownOuter.hasTag(CLASS) && site != ownOuter) {
                         Type normOuter = site;
-                        if (normOuter.hasTag(CLASS))
+                        if (normOuter.hasTag(CLASS)) {
                             normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
+                            if (site.getKind() == TypeKind.ANNOTATED) {
+                                // Propagate any type annotations.
+                                // TODO: should asEnclosingSuper do this?
+                                // Note that the type annotations in site will be updated
+                                // by annotateType. Therefore, modify site instead
+                                // of creating a new AnnotatedType.
+                                ((AnnotatedType)site).underlyingType = normOuter;
+                                normOuter = site;
+                            }
+                        }
                         if (normOuter == null) // perhaps from an import
                             normOuter = types.erasure(ownOuter);
                         if (normOuter != ownOuter)
@@ -3432,6 +3554,15 @@
             env.info.defaultSuperCallSite = null;
         }
 
+        if (sym.isStatic() && site.isInterface()) {
+            Assert.check(env.tree.hasTag(APPLY));
+            JCMethodInvocation app = (JCMethodInvocation)env.tree;
+            if (app.meth.hasTag(SELECT) &&
+                    !TreeInfo.isStaticSelector(((JCFieldAccess)app.meth).selected, names)) {
+                log.error(env.tree.pos(), "illegal.static.intf.meth.call", site);
+            }
+        }
+
         // Compute the identifier's instantiated type.
         // For methods, we need to compute the instance type by
         // Resolve.instantiate from the symbol's type as well as
@@ -3587,8 +3718,15 @@
         tree.type = result = checkIntersection(tree, tree.bounds);
     }
 
-     public void visitTypeParameter(JCTypeParameter tree) {
-        TypeVar typeVar = (TypeVar)tree.type;
+    public void visitTypeParameter(JCTypeParameter tree) {
+        TypeVar typeVar = (TypeVar) tree.type;
+
+        if (tree.annotations != null && tree.annotations.nonEmpty()) {
+            AnnotatedType antype = new AnnotatedType(typeVar);
+            annotateType(antype, tree.annotations);
+            tree.type = antype;
+        }
+
         if (!typeVar.bound.isErroneous()) {
             //fixup type-parameter bound computed in 'attribTypeVariables'
             typeVar.bound = checkIntersection(tree, tree.bounds);
@@ -3684,6 +3822,44 @@
         result = tree.type = syms.errType;
     }
 
+    public void visitAnnotatedType(JCAnnotatedType tree) {
+        Type underlyingType = attribType(tree.getUnderlyingType(), env);
+        this.attribAnnotationTypes(tree.annotations, env);
+        AnnotatedType antype = new AnnotatedType(underlyingType);
+        annotateType(antype, tree.annotations);
+        result = tree.type = antype;
+    }
+
+    /**
+     * Apply the annotations to the particular type.
+     */
+    public void annotateType(final AnnotatedType type, final List<JCAnnotation> annotations) {
+        if (annotations.isEmpty())
+            return;
+        annotate.typeAnnotation(new Annotate.Annotator() {
+            @Override
+            public String toString() {
+                return "annotate " + annotations + " onto " + type;
+            }
+            @Override
+            public void enterAnnotation() {
+                List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
+                type.typeAnnotations = compounds;
+            }
+        });
+    }
+
+    private static List<Attribute.TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
+        if (annotations.isEmpty())
+            return List.nil();
+
+        ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
+        for (JCAnnotation anno : annotations) {
+            buf.append((Attribute.TypeCompound) anno.attribute);
+        }
+        return buf.toList();
+    }
+
     public void visitErroneous(JCErroneous tree) {
         if (tree.errs != null)
             for (JCTree err : tree.errs)
@@ -3844,24 +4020,14 @@
                 log.error(tree.typarams.head.pos(),
                           "intf.annotation.cant.have.type.params");
 
-            // If this annotation has a @ContainedBy, validate
-            Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym);
-            if (containedBy != null) {
-                // get diagnositc position for error reporting
-                DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type);
+            // If this annotation has a @Repeatable, validate
+            Attribute.Compound repeatable = c.attribute(syms.repeatableType.tsym);
+            if (repeatable != null) {
+                // get diagnostic position for error reporting
+                DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type);
                 Assert.checkNonNull(cbPos);
 
-                chk.validateContainedBy(c, containedBy, cbPos);
-            }
-
-            // If this annotation has a @ContainerFor, validate
-            Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym);
-            if (containerFor != null) {
-                // get diagnositc position for error reporting
-                DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type);
-                Assert.checkNonNull(cfPos);
-
-                chk.validateContainerFor(c, containerFor, cfPos);
+                chk.validateRepeatable(c, repeatable, cbPos);
             }
         } else {
             // Check that all extended classes and interfaces
@@ -3925,6 +4091,12 @@
             (c.flags() & ABSTRACT) == 0) {
             checkSerialVersionUID(tree, c);
         }
+
+        // Correctly organize the postions of the type annotations
+        TypeAnnotations.organizeTypeAnnotationsBodies(this.syms, this.names, this.log, tree);
+
+        // Check type annotations applicability rules
+        validateTypeAnnotations(tree);
     }
         // where
         /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
@@ -3982,6 +4154,94 @@
         return types.capture(type);
     }
 
+    private void validateTypeAnnotations(JCTree tree) {
+        tree.accept(typeAnnotationsValidator);
+    }
+    //where
+    private final JCTree.Visitor typeAnnotationsValidator =
+        new TreeScanner() {
+        public void visitAnnotation(JCAnnotation tree) {
+            if (tree.hasTag(TYPE_ANNOTATION)) {
+                // TODO: It seems to WMD as if the annotation in
+                // parameters, in particular also the recvparam, are never
+                // of type JCTypeAnnotation and therefore never checked!
+                // Luckily this check doesn't really do anything that isn't
+                // also done elsewhere.
+                chk.validateTypeAnnotation(tree, false);
+            }
+            super.visitAnnotation(tree);
+        }
+        public void visitTypeParameter(JCTypeParameter tree) {
+            chk.validateTypeAnnotations(tree.annotations, true);
+            scan(tree.bounds);
+            // Don't call super.
+            // This is needed because above we call validateTypeAnnotation with
+            // false, which would forbid annotations on type parameters.
+            // super.visitTypeParameter(tree);
+        }
+        public void visitMethodDef(JCMethodDecl tree) {
+            // Static methods cannot have receiver type annotations.
+            // In test case FailOver15.java, the nested method getString has
+            // a null sym, because an unknown class is instantiated.
+            // I would say it's safe to skip.
+            if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) {
+                if (tree.recvparam != null) {
+                    // TODO: better error message. Is the pos good?
+                    log.error(tree.recvparam.pos(), "annotation.type.not.applicable");
+                }
+            }
+            if (tree.restype != null && tree.restype.type != null) {
+                validateAnnotatedType(tree.restype, tree.restype.type);
+            }
+            super.visitMethodDef(tree);
+        }
+        public void visitVarDef(final JCVariableDecl tree) {
+            if (tree.sym != null && tree.sym.type != null)
+                validateAnnotatedType(tree, tree.sym.type);
+            super.visitVarDef(tree);
+        }
+        public void visitTypeCast(JCTypeCast tree) {
+            if (tree.clazz != null && tree.clazz.type != null)
+                validateAnnotatedType(tree.clazz, tree.clazz.type);
+            super.visitTypeCast(tree);
+        }
+        public void visitTypeTest(JCInstanceOf tree) {
+            if (tree.clazz != null && tree.clazz.type != null)
+                validateAnnotatedType(tree.clazz, tree.clazz.type);
+            super.visitTypeTest(tree);
+        }
+        // TODO: what else do we need?
+        // public void visitNewClass(JCNewClass tree) {
+        // public void visitNewArray(JCNewArray tree) {
+
+        /* I would want to model this after
+         * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
+         * and override visitSelect and visitTypeApply.
+         * However, we only set the annotated type in the top-level type
+         * of the symbol.
+         * Therefore, we need to override each individual location where a type
+         * can occur.
+         */
+        private void validateAnnotatedType(final JCTree errtree, final Type type) {
+            if (type.getEnclosingType() != null &&
+                    type != type.getEnclosingType()) {
+                validateEnclosingAnnotatedType(errtree, type.getEnclosingType());
+            }
+            for (Type targ : type.getTypeArguments()) {
+                validateAnnotatedType(errtree, targ);
+            }
+        }
+        private void validateEnclosingAnnotatedType(final JCTree errtree, final Type type) {
+            validateAnnotatedType(errtree, type);
+            if (type.tsym != null &&
+                    type.tsym.isStatic() &&
+                    type.getAnnotations().nonEmpty()) {
+                    // Enclosing static classes cannot have type annotations.
+                log.error(errtree.pos(), "cant.annotate.static.class");
+            }
+        }
+    };
+
     // <editor-fold desc="post-attribution visitor">
 
     /**
@@ -4088,11 +4348,28 @@
         }
 
         @Override
+        public void visitLambda(JCLambda that) {
+            super.visitLambda(that);
+            if (that.descriptorType == null) {
+                that.descriptorType = syms.unknownType;
+            }
+            if (that.targets == null) {
+                that.targets = List.nil();
+            }
+        }
+
+        @Override
         public void visitReference(JCMemberReference that) {
             super.visitReference(that);
             if (that.sym == null) {
                 that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol);
             }
+            if (that.descriptorType == null) {
+                that.descriptorType = syms.unknownType;
+            }
+            if (that.targets == null) {
+                that.targets = List.nil();
+            }
         }
     }
     // </editor-fold>
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 package com.sun.tools.javac.comp;
 
 import java.util.*;
-import java.util.Set;
+
 import javax.tools.JavaFileManager;
 
 import com.sun.tools.javac.code.*;
@@ -36,7 +36,6 @@
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
 
-import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.code.Lint;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Type.*;
@@ -44,6 +43,8 @@
 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.tree.JCTree.*;
+import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
@@ -100,6 +101,9 @@
         context.put(checkKey, this);
 
         names = Names.instance(context);
+        dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
+            names.FIELD, names.METHOD, names.CONSTRUCTOR,
+            names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
         log = Log.instance(context);
         rs = Resolve.instance(context);
         syms = Symtab.instance(context);
@@ -571,34 +575,27 @@
         if (!tree.type.isErroneous() &&
                 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST))
                 && types.isSameType(tree.expr.type, tree.clazz.type)
+                && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
                 && !is292targetTypeCast(tree)) {
             log.warning(Lint.LintCategory.CAST,
                     tree.pos(), "redundant.cast", tree.expr.type);
         }
     }
     //where
-            private boolean is292targetTypeCast(JCTypeCast tree) {
-                boolean is292targetTypeCast = false;
-                JCExpression expr = TreeInfo.skipParens(tree.expr);
-                if (expr.hasTag(APPLY)) {
-                    JCMethodInvocation apply = (JCMethodInvocation)expr;
-                    Symbol sym = TreeInfo.symbol(apply.meth);
-                    is292targetTypeCast = sym != null &&
-                        sym.kind == MTH &&
-                        (sym.flags() & HYPOTHETICAL) != 0;
-                }
-                return is292targetTypeCast;
+        private boolean is292targetTypeCast(JCTypeCast tree) {
+            boolean is292targetTypeCast = false;
+            JCExpression expr = TreeInfo.skipParens(tree.expr);
+            if (expr.hasTag(APPLY)) {
+                JCMethodInvocation apply = (JCMethodInvocation)expr;
+                Symbol sym = TreeInfo.symbol(apply.meth);
+                is292targetTypeCast = sym != null &&
+                    sym.kind == MTH &&
+                    (sym.flags() & HYPOTHETICAL) != 0;
             }
+            return is292targetTypeCast;
+        }
 
-
-
-//where
-        /** Is type a type variable, or a (possibly multi-dimensional) array of
-         *  type variables?
-         */
-        boolean isTypeVar(Type t) {
-            return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t));
-        }
+        private static final boolean ignoreAnnotatedCasts = true;
 
     /** Check that a type is within some bounds.
      *
@@ -634,25 +631,40 @@
         }
     }
 
+    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
+        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
+            return typeTagError(pos,
+                                diags.fragment("type.req.class.array"),
+                                asTypeParam(t));
+        } else {
+            return t;
+        }
+    }
+
     /** Check that type is a class or interface type.
      *  @param pos           Position to be used for error reporting.
      *  @param t             The type to be checked.
      */
     Type checkClassType(DiagnosticPosition pos, Type t) {
-        if (!t.hasTag(CLASS) && !t.hasTag(ERROR))
+        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
             return typeTagError(pos,
                                 diags.fragment("type.req.class"),
-                                (t.hasTag(TYPEVAR))
-                                ? diags.fragment("type.parameter", t)
-                                : t);
-        else
+                                asTypeParam(t));
+        } else {
             return t;
+        }
     }
+    //where
+        private Object asTypeParam(Type t) {
+            return (t.hasTag(TYPEVAR))
+                                    ? diags.fragment("type.parameter", t)
+                                    : t;
+        }
 
     /** Check that type is a valid qualifier for a constructor reference expression
      */
     Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
-        t = checkClassType(pos, t);
+        t = checkClassOrArrayType(pos, t);
         if (t.hasTag(CLASS)) {
             if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
                 log.error(pos, "abstract.cant.be.instantiated");
@@ -690,11 +702,8 @@
      *  @param t             The type to be checked.
      */
     Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
-        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
-            return typeTagError(pos,
-                                diags.fragment("type.req.class.array"),
-                                t);
-        } else if (!types.isReifiable(t)) {
+        t = checkClassOrArrayType(pos, t);
+        if (!t.isErroneous() && !types.isReifiable(t)) {
             log.error(pos, "illegal.generic.type.for.instof");
             return types.createErrorType(t);
         } else {
@@ -840,7 +849,7 @@
         // System.out.println("actuals: " + argtypes);
         List<Type> formals = owntype.getParameterTypes();
         Type last = useVarargs ? formals.last() : null;
-        if (sym.name==names.init &&
+        if (sym.name == names.init &&
                 sym.owner == syms.enumSym)
                 formals = formals.tail.tail;
         List<JCExpression> args = argtrees;
@@ -888,7 +897,6 @@
                    syms.methodClass);
         }
         if (useVarargs) {
-            JCTree tree = env.tree;
             Type argtype = owntype.getParameterTypes().last();
             if (!types.isReifiable(argtype) &&
                     (!allowSimplifiedVarargs ||
@@ -899,22 +907,13 @@
                                   argtype);
             }
             if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
-                Type elemtype = types.elemtype(argtype);
-                switch (tree.getTag()) {
-                    case APPLY:
-                        ((JCMethodInvocation) tree).varargsElement = elemtype;
-                        break;
-                    case NEWCLASS:
-                        ((JCNewClass) tree).varargsElement = elemtype;
-                        break;
-                    case REFERENCE:
-                        ((JCMemberReference) tree).varargsElement = elemtype;
-                        break;
-                    default:
-                        throw new AssertionError(""+tree);
-                }
+                TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
             }
          }
+         PolyKind pkind = (sym.type.hasTag(FORALL) &&
+                 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
+                 PolyKind.POLY : PolyKind.STANDALONE;
+         TreeInfo.setPolyKind(env.tree, pkind);
          return owntype;
     }
     //where
@@ -1055,9 +1054,12 @@
                 } else
                     mask = ConstructorFlags;
             }  else if ((sym.owner.flags_field & INTERFACE) != 0) {
-                if ((flags & DEFAULT) != 0) {
-                    mask = InterfaceDefaultMethodMask;
-                    implicit = PUBLIC | ABSTRACT;
+                if ((flags & (DEFAULT | STATIC)) != 0) {
+                    mask = InterfaceMethodMask;
+                    implicit = PUBLIC;
+                    if ((flags & DEFAULT) != 0) {
+                        implicit |= ABSTRACT;
+                    }
                 } else {
                     mask = implicit = InterfaceMethodFlags;
                 }
@@ -1127,6 +1129,10 @@
                                 PRIVATE | STATIC | DEFAULT))
                  &&
                  checkDisjoint(pos, flags,
+                                STATIC,
+                                DEFAULT)
+                 &&
+                 checkDisjoint(pos, flags,
                                ABSTRACT | INTERFACE,
                                FINAL | NATIVE | SYNCHRONIZED)
                  &&
@@ -1316,6 +1322,11 @@
             }
         }
 
+        @Override
+        public void visitAnnotatedType(JCAnnotatedType tree) {
+            tree.underlyingType.accept(this);
+        }
+
         /** Default visitor method: do nothing.
          */
         @Override
@@ -2236,7 +2247,7 @@
     void checkImplementations(JCClassDecl tree) {
         checkImplementations(tree, tree.sym, tree.sym);
     }
-//where
+    //where
         /** Check that all methods which implement some
          *  method in `ic' conform to the method they implement.
          */
@@ -2577,6 +2588,13 @@
             validateAnnotation(a, s);
     }
 
+    /** Check the type annotations.
+     */
+    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
+        for (JCAnnotation a : annotations)
+            validateTypeAnnotation(a, isTypeParameter);
+    }
+
     /** Check an annotation of a symbol.
      */
     private void validateAnnotation(JCAnnotation a, Symbol s) {
@@ -2589,33 +2607,53 @@
             if (!isOverrider(s))
                 log.error(a.pos(), "method.does.not.override.superclass");
         }
+
+        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
+            if (s.kind != TYP) {
+                log.error(a.pos(), "bad.functional.intf.anno");
+            } else {
+                try {
+                    types.findDescriptorSymbol((TypeSymbol)s);
+                } catch (Types.FunctionDescriptorLookupError ex) {
+                    log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic());
+                }
+            }
+        }
+    }
+
+    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
+        Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a);
+        validateAnnotationTree(a);
+
+        if (!isTypeAnnotation(a, isTypeParameter))
+            log.error(a.pos(), "annotation.type.not.applicable");
     }
 
     /**
-     * Validate the proposed container 'containedBy' on the
+     * Validate the proposed container 'repeatable' on the
      * annotation type symbol 's'. Report errors at position
      * 'pos'.
      *
-     * @param s The (annotation)type declaration annotated with a @ContainedBy
-     * @param containedBy the @ContainedBy on 's'
+     * @param s The (annotation)type declaration annotated with a @Repeatable
+     * @param repeatable the @Repeatable on 's'
      * @param pos where to report errors
      */
-    public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
-        Assert.check(types.isSameType(containedBy.type, syms.containedByType));
+    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
+        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
 
         Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
         if (!l.isEmpty()) {
             Assert.check(l.head.fst.name == names.value);
             t = ((Attribute.Class)l.head.snd).getValue();
         }
 
         if (t == null) {
-            log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
+            // errors should already have been reported during Annotate
             return;
         }
 
-        validateHasContainerFor(t.tsym, s, pos);
+        validateValue(t.tsym, s, pos);
         validateRetention(t.tsym, s, pos);
         validateDocumented(t.tsym, s, pos);
         validateInherited(t.tsym, s, pos);
@@ -2623,79 +2661,18 @@
         validateDefault(t.tsym, s, pos);
     }
 
-    /**
-     * Validate the proposed container 'containerFor' on the
-     * annotation type symbol 's'. Report errors at position
-     * 'pos'.
-     *
-     * @param s The (annotation)type declaration annotated with a @ContainerFor
-     * @param containerFor the @ContainedFor on 's'
-     * @param pos where to report errors
-     */
-    public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
-        Assert.check(types.isSameType(containerFor.type, syms.containerForType));
-
-        Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
-        if (!l.isEmpty()) {
-            Assert.check(l.head.fst.name == names.value);
-            t = ((Attribute.Class)l.head.snd).getValue();
+    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+        Scope.Entry e = container.members().lookup(names.value);
+        if (e.scope != null && e.sym.kind == MTH) {
+            MethodSymbol m = (MethodSymbol) e.sym;
+            Type ret = m.getReturnType();
+            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
+                log.error(pos, "invalid.repeatable.annotation.value.return",
+                        container, ret, types.makeArrayType(contained.type));
+            }
+        } else {
+            log.error(pos, "invalid.repeatable.annotation.no.value", container);
         }
-
-        if (t == null) {
-            log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
-            return;
-        }
-
-        validateHasContainedBy(t.tsym, s, pos);
-    }
-
-    private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
-        Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
-
-        if (containedBy == null) {
-            log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
-            return;
-        }
-
-        Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
-        if (!l.isEmpty()) {
-            Assert.check(l.head.fst.name == names.value);
-            t = ((Attribute.Class)l.head.snd).getValue();
-        }
-
-        if (t == null) {
-            log.error(pos, "invalid.container.wrong.containedby", container, contained);
-            return;
-        }
-
-        if (!types.isSameType(t, contained.type))
-            log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
-    }
-
-    private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
-        Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
-
-        if (containerFor == null) {
-            log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
-            return;
-        }
-
-        Type t = null;
-        List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
-        if (!l.isEmpty()) {
-            Assert.check(l.head.fst.name == names.value);
-            t = ((Attribute.Class)l.head.snd).getValue();
-        }
-
-        if (t == null) {
-            log.error(pos, "invalid.container.wrong.containerfor", container, contained);
-            return;
-        }
-
-        if (!types.isSameType(t, contained.type))
-            log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
     }
 
     private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
@@ -2715,7 +2692,7 @@
             }
         }
         if (error ) {
-            log.error(pos, "invalid.containedby.annotation.retention",
+            log.error(pos, "invalid.repeatable.annotation.retention",
                       container, containerRetention,
                       contained, containedRetention);
         }
@@ -2724,7 +2701,7 @@
     private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
         if (contained.attribute(syms.documentedType.tsym) != null) {
             if (container.attribute(syms.documentedType.tsym) == null) {
-                log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
+                log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
             }
         }
     }
@@ -2732,7 +2709,7 @@
     private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
         if (contained.attribute(syms.inheritedType.tsym) != null) {
             if (container.attribute(syms.inheritedType.tsym) == null) {
-                log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
+                log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
             }
         }
     }
@@ -2752,7 +2729,7 @@
         // contained has target, but container has not, error
         Attribute.Array containerTarget = getAttributeTargetAttribute(container);
         if (containerTarget == null) {
-            log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
             return;
         }
 
@@ -2775,7 +2752,7 @@
         }
 
         if (!isTargetSubset(containedTargets, containerTargets)) {
-            log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
         }
     }
 
@@ -2809,7 +2786,7 @@
                 elm.kind == Kinds.MTH &&
                 ((MethodSymbol)elm).defaultValue == null) {
                 log.error(pos,
-                          "invalid.containedby.annotation.elem.nondefault",
+                          "invalid.repeatable.annotation.elem.nondefault",
                           container,
                           elm);
             }
@@ -2834,45 +2811,90 @@
         return false;
     }
 
+    /** Is the annotation applicable to type annotations? */
+    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
+        Attribute.Compound atTarget =
+            a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
+        if (atTarget == null) {
+            // An annotation without @Target is not a type annotation.
+            return false;
+        }
+
+        Attribute atValue = atTarget.member(names.value);
+        if (!(atValue instanceof Attribute.Array)) {
+            return false; // error recovery
+        }
+
+        Attribute.Array arr = (Attribute.Array) atValue;
+        for (Attribute app : arr.values) {
+            if (!(app instanceof Attribute.Enum)) {
+                return false; // recovery
+            }
+            Attribute.Enum e = (Attribute.Enum) app;
+
+            if (e.value.name == names.TYPE_USE)
+                return true;
+            else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER)
+                return true;
+        }
+        return false;
+    }
+
     /** Is the annotation applicable to the symbol? */
     boolean annotationApplicable(JCAnnotation a, Symbol s) {
         Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
+        Name[] targets;
+
         if (arr == null) {
-            return true;
+            targets = defaultTargetMetaInfo(a, s);
+        } else {
+            // TODO: can we optimize this?
+            targets = new Name[arr.values.length];
+            for (int i=0; i<arr.values.length; ++i) {
+                Attribute app = arr.values[i];
+                if (!(app instanceof Attribute.Enum)) {
+                    return true; // recovery
+                }
+                Attribute.Enum e = (Attribute.Enum) app;
+                targets[i] = e.value.name;
+            }
         }
-        for (Attribute app : arr.values) {
-            if (!(app instanceof Attribute.Enum)) return true; // recovery
-            Attribute.Enum e = (Attribute.Enum) app;
-            if (e.value.name == names.TYPE)
+        for (Name target : targets) {
+            if (target == names.TYPE)
                 { if (s.kind == TYP) return true; }
-            else if (e.value.name == names.FIELD)
+            else if (target == names.FIELD)
                 { if (s.kind == VAR && s.owner.kind != MTH) return true; }
-            else if (e.value.name == names.METHOD)
+            else if (target == names.METHOD)
                 { if (s.kind == MTH && !s.isConstructor()) return true; }
-            else if (e.value.name == names.PARAMETER)
+            else if (target == names.PARAMETER)
                 { if (s.kind == VAR &&
                       s.owner.kind == MTH &&
                       (s.flags() & PARAMETER) != 0)
                     return true;
                 }
-            else if (e.value.name == names.CONSTRUCTOR)
+            else if (target == names.CONSTRUCTOR)
                 { if (s.kind == MTH && s.isConstructor()) return true; }
-            else if (e.value.name == names.LOCAL_VARIABLE)
+            else if (target == names.LOCAL_VARIABLE)
                 { if (s.kind == VAR && s.owner.kind == MTH &&
                       (s.flags() & PARAMETER) == 0)
                     return true;
                 }
-            else if (e.value.name == names.ANNOTATION_TYPE)
+            else if (target == names.ANNOTATION_TYPE)
                 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
                     return true;
                 }
-            else if (e.value.name == names.PACKAGE)
+            else if (target == names.PACKAGE)
                 { if (s.kind == PCK) return true; }
-            else if (e.value.name == names.TYPE_USE)
+            else if (target == names.TYPE_USE)
                 { if (s.kind == TYP ||
                       s.kind == VAR ||
                       (s.kind == MTH && !s.isConstructor() &&
-                       !s.type.getReturnType().hasTag(VOID)))
+                      !s.type.getReturnType().hasTag(VOID)) ||
+                      (s.kind == MTH && s.isConstructor()))
+                    return true;
+                }
+            else if (target == names.TYPE_PARAMETER)
+                { if (s.kind == TYP && s.type.hasTag(TYPEVAR))
                     return true;
                 }
             else
@@ -2891,6 +2913,11 @@
         return (Attribute.Array) atValue;
     }
 
+    private final Name[] dfltTargetMeta;
+    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
+        return dfltTargetMeta;
+    }
+
     /** Check an annotation value.
      *
      * @param a The annotation tree to check
--- a/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/ConstFold.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,6 @@
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.util.*;
 
-import com.sun.tools.javac.code.Type.*;
-
 import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
 
 import static com.sun.tools.javac.jvm.ByteCodes.*;
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Sat Jan 26 19:24:46 2013 -0800
@@ -65,6 +65,7 @@
 
     final Attr attr;
     final Check chk;
+    final JCDiagnostic.Factory diags;
     final Enter enter;
     final Infer infer;
     final Log log;
@@ -83,14 +84,20 @@
         context.put(deferredAttrKey, this);
         attr = Attr.instance(context);
         chk = Check.instance(context);
+        diags = JCDiagnostic.Factory.instance(context);
         enter = Enter.instance(context);
         infer = Infer.instance(context);
         log = Log.instance(context);
         syms = Symtab.instance(context);
         make = TreeMaker.instance(context);
         types = Types.instance(context);
+        Names names = Names.instance(context);
+        stuckTree = make.Ident(names.empty).setType(Type.noType);
     }
 
+    /** shared tree for stuck expressions */
+    final JCTree stuckTree;
+
     /**
      * This type represents a deferred type. A deferred type starts off with
      * no information on the underlying expression type. Such info needs to be
@@ -356,12 +363,11 @@
                 //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.isStuck()) {
-                        deferredAttrNode.process();
+                    if (!deferredAttrNode.process()) {
+                        stuckVars.addAll(deferredAttrNode.stuckVars);
+                    } else {
                         deferredAttrNodes.remove(deferredAttrNode);
                         progress = true;
-                    } else {
-                        stuckVars.addAll(deferredAttrNode.stuckVars);
                     }
                 }
                 if (!progress) {
@@ -404,21 +410,88 @@
             }
 
             /**
-             * is this node stuck?
+             * Process a deferred attribution node.
+             * Invariant: a stuck node cannot be processed.
              */
-            boolean isStuck() {
-                return stuckVars.nonEmpty();
+            @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");
+                }
             }
 
             /**
-             * Process a deferred attribution node.
-             * Invariant: a stuck node cannot be processed.
+             * Structural checker for stuck expressions
              */
-            void process() {
-                if (isStuck()) {
-                    throw new IllegalStateException("Cannot process a stuck deferred node");
+            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;
                 }
-                dt.check(resultInfo);
+
+                @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());
+                        }
+                    }
+                }
             }
         }
     }
@@ -624,12 +697,12 @@
             if (inferenceContext.inferenceVars().contains(pt)) {
                 stuckVars.add(pt);
             }
-            if (!types.isFunctionalInterface(pt.tsym)) {
+            if (!types.isFunctionalInterface(pt)) {
                 return;
             }
             Type descType = types.findDescriptorType(pt);
             List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
-            if (!TreeInfo.isExplicitLambda(tree) &&
+            if (tree.paramKind == JCLambda.ParameterKind.IMPLICIT &&
                     freeArgVars.nonEmpty()) {
                 stuckVars.addAll(freeArgVars);
             }
@@ -643,7 +716,7 @@
                 stuckVars.add(pt);
                 return;
             }
-            if (!types.isFunctionalInterface(pt.tsym)) {
+            if (!types.isFunctionalInterface(pt)) {
                 return;
             }
 
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -131,7 +131,11 @@
 
         predefClassDef = make.ClassDef(
             make.Modifiers(PUBLIC),
-            syms.predefClass.name, null, null, null, null);
+            syms.predefClass.name,
+            List.<JCTypeParameter>nil(),
+            null,
+            List.<JCExpression>nil(),
+            List.<JCTree>nil());
         predefClassDef.sym = syms.predefClass;
         todo = Todo.instance(context);
         fileManager = context.get(JavaFileManager.class);
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Sat Jan 26 19:24:46 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.tree.JCTree.*;
 
 import static com.sun.tools.javac.code.Flags.*;
@@ -2175,6 +2176,11 @@
             unrefdResources.remove(sym);
         }
 
+        public void visitAnnotatedType(JCAnnotatedType tree) {
+            // annotations don't get scanned
+            tree.underlyingType.accept(this);
+        }
+
         public void visitTopLevel(JCCompilationUnit tree) {
             // Do nothing for TopLevel since each class is visited individually
         }
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Sat Jan 26 19:24:46 2013 -0800
@@ -66,6 +66,9 @@
     Log log;
     JCDiagnostic.Factory diags;
 
+    /** Should we inject return-type constraints earlier? */
+    boolean allowEarlyReturnConstraints;
+
     public static Infer instance(Context context) {
         Infer instance = context.get(inferKey);
         if (instance == null)
@@ -83,6 +86,7 @@
         chk = Check.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         inferenceException = new InferenceException(diags);
+        allowEarlyReturnConstraints = Source.instance(context).allowEarlyReturnConstraints();
     }
 
    /**
@@ -188,19 +192,6 @@
             MethodType mtype,
             Attr.ResultInfo resultInfo,
             Warner warn) throws InferenceException {
-        Type to = resultInfo.pt;
-        if (to.hasTag(NONE) || resultInfo.checkContext.inferenceContext().free(resultInfo.pt)) {
-            to = mtype.getReturnType().isPrimitiveOrVoid() ?
-                    mtype.getReturnType() : syms.objectType;
-        }
-        Type qtype1 = inferenceContext.asFree(mtype.getReturnType(), types);
-        if (!types.isSubtype(qtype1,
-                qtype1.hasTag(UNDETVAR) ? types.boxedTypeOrType(to) : to)) {
-            throw inferenceException
-                    .setMessage("infer.no.conforming.instance.exists",
-                    inferenceContext.restvars(), mtype.getReturnType(), to);
-        }
-
         while (true) {
             boolean stuck = true;
             for (Type t : inferenceContext.undetvars) {
@@ -283,6 +274,11 @@
         try {
             methodCheck.argumentsAcceptable(env, deferredAttrContext, argtypes, mt.getParameterTypes(), warn);
 
+            if (resultInfo != null && allowEarlyReturnConstraints &&
+                    !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+                generateReturnConstraints(mt, inferenceContext, resultInfo);
+            }
+
             deferredAttrContext.complete();
 
             // minimize as yet undetermined type variables
@@ -298,6 +294,9 @@
 
             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);
@@ -313,6 +312,25 @@
             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.
      */
@@ -461,52 +479,40 @@
             Type formalInterface = funcInterface.tsym.type;
             InferenceContext funcInterfaceContext =
                     new InferenceContext(funcInterface.tsym.type.getTypeArguments(), this, false);
-            if (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"));
+            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);
                 }
-                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;
+                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);
                 }
-                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);
-                    }
-                }
-
-                formalInterface = funcInterfaceContext.asInstType(formalInterface, types);
-            }
-            ListBuffer<Type> typeargs = ListBuffer.lb();
-            List<Type> actualTypeargs = funcInterface.getTypeArguments();
-            //for remaining uninferred type-vars in the functional interface type,
-            //simply replace the wildcards with its bound
-            for (Type t : formalInterface.getTypeArguments()) {
-                if (actualTypeargs.head.hasTag(WILDCARD)) {
-                    WildcardType wt = (WildcardType)actualTypeargs.head;
-                    typeargs.append(wt.type);
-                } else {
-                    typeargs.append(actualTypeargs.head);
+                if (uv.inst == null) {
+                    uv.inst = actualTypeargs.head;
                 }
                 actualTypeargs = actualTypeargs.tail;
             }
-            Type owntype = types.subst(formalInterface, funcInterfaceContext.inferenceVars(), typeargs.toList());
+            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 types.createErrorType(funcInterface);
             }
             return owntype;
         }
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Thu Jan 24 16:49:37 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Sat Jan 26 19:24:46 2013 -0800
@@ -253,7 +253,7 @@
         int refKind = referenceKind(sym);
 
         //convert to an invokedynamic call
-        result = makeMetaFactoryIndyCall(tree, tree.targetType, refKind, sym, indy_args);
+        result = makeMetaFactoryIndyCall(tree, refKind, sym, indy_args);
     }
 
     private JCIdent makeThis(Type type, Symbol owner) {
@@ -302,6 +302,7 @@
             case UNBOUND:           /** Type :: instMethod */
             case STATIC:            /** Type :: staticMethod */
             case TOPLEVEL:          /** Top level :: new */
+            case ARRAY_CTOR:        /** ArrayType :: new */
                 init = null;
                 break;
 
@@ -313,7 +314,7 @@
 
 
         //build a sam instance using an indy call to the meta-factory
-        result = makeMetaFactoryIndyCall(tree, tree.targetType, localContext.referenceKind(), refSym, indy_args);
+        result = makeMetaFactoryIndyCall(tree, localContext.referenceKind(), refSym, indy_args);
     }
 
     /**
@@ -502,19 +503,6 @@
 
     // </editor-fold>
 
-    private MethodSymbol makeSamDescriptor(Type targetType) {
-        return (MethodSymbol)types.findDescriptorSymbol(targetType.tsym);
-    }
-
-    private Type makeFunctionalDescriptorType(Type targetType, MethodSymbol samDescriptor, boolean erased) {
-        Type descType = types.memberType(targetType, samDescriptor);
-        return erased ? types.erasure(descType) : descType;
-    }
-
-    private Type makeFunctionalDescriptorType(Type targetType, boolean erased) {
-        return makeFunctionalDescriptorType(targetType, makeSamDescriptor(targetType), erased);
-    }
-
     /**
      * Generate an adapter method "bridge" for a method reference which cannot
      * be used directly.
@@ -645,24 +633,33 @@
          * to the first bridge synthetic parameter
          */
         private JCExpression bridgeExpressionNew() {
-            JCExpression encl = null;
-            switch (tree.kind) {