7151010: Add compiler support for repeating annotations
authorjfranck
Fri, 31 Aug 2012 10:37:46 +0100
changeset 13689 4d519199a6aa
parent 13636 bee2d435e11f
child 13690 8be9ba21c4a9
7151010: Add compiler support for repeating annotations Reviewed-by: jjg, mcimadamore
langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java
langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java
langtools/src/share/classes/com/sun/tools/javac/code/Lint.java
langtools/src/share/classes/com/sun/tools/javac/code/Source.java
langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java
langtools/src/share/classes/com/sun/tools/javac/code/Types.java
langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java
langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java
langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java
langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java
langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java
langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java
langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java
langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java
langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java
langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java
langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java
langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java
langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java
langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java
langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java
langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java
langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java
langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java
langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java
langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java
langtools/test/tools/javac/diags/examples.not-yet.txt
langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java
langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java
langtools/test/tools/javac/diags/examples/ContainedByNoValue.java
langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java
langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java
langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java
langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java
langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java
langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java
langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java
langtools/test/tools/javac/diags/examples/WrongContainedBy.java
langtools/test/tools/javac/diags/examples/WrongContainerFor.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import java.util.Map;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Pair;
+
+import static com.sun.tools.javac.code.Kinds.PCK;
+import com.sun.tools.javac.util.*;
+
+/**
+ * Container for all annotations (attributes in javac) on a Symbol.
+ *
+ * This class is explicitly mutable. Its contents will change when attributes
+ * are annotated onto the Symbol. However this class depends on the facts that
+ * List (in javac) is immutable.
+ *
+ * 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
+ * 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.
+ *
+ * IN_PROGRESS annotations have been found on the declaration. Will be processed
+ * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
+ * of attributes (and this moves out of the IN_PROGRESS state).
+ *
+ * "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().
+ *
+ * <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 Annotations {
+
+    private static final List<Attribute.Compound> NOT_STARTED = List.of(null);
+    private static final List<Attribute.Compound> IN_PROGRESS = List.of(null);
+    /*
+     * This field should never be null
+     */
+    private List<Attribute.Compound> attributes = NOT_STARTED;
+    /*
+     * The Symbol this Annotatios belong to
+     */
+    private final Symbol s;
+
+    public Annotations(Symbol s) {
+        this.s = s;
+    }
+
+    public List<Attribute.Compound> getAttributes() {
+        return filterSentinels(attributes);
+    }
+
+    public void setAttributes(List<Attribute.Compound> a) {
+        Assert.check(pendingCompletion() || !isStarted());
+        if (a == null) {
+            throw new NullPointerException();
+        }
+        attributes = a;
+    }
+
+    public void setAttributes(Annotations other) {
+        if (other == null) {
+            throw new NullPointerException();
+        }
+        setAttributes(other.getAttributes());
+    }
+
+    public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) {
+        Assert.check(pendingCompletion() || (!isStarted() && s.kind == PCK));
+
+        Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated = ctx.annotated;
+        boolean atLeastOneRepeated = false;
+        List<Attribute.Compound> buf = List.<Attribute.Compound>nil();
+        for (ListBuffer<Attribute.Compound> lb : annotated.values()) {
+            if (lb.size() == 1) {
+                buf = buf.prepend(lb.first());
+            } else { // repeated
+                buf = buf.prepend(new Placeholder(lb.toList(), s));
+                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
+            // repeating annotations.
+            //
+            // 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
+            // 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
+            // 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: " + s + " in: " + s.owner;
+                }
+
+                @Override
+                public void enterAnnotation() {
+                    complete(ctx);
+                }
+            });
+        }
+    }
+
+    public Annotations reset() {
+        attributes = IN_PROGRESS;
+        return this;
+    }
+
+    public boolean isEmpty() {
+        return !isStarted()
+                || pendingCompletion()
+                || attributes.isEmpty();
+    }
+
+    public boolean pendingCompletion() {
+        return attributes == IN_PROGRESS;
+    }
+
+    public Annotations append(List<Attribute.Compound> l) {
+        attributes = filterSentinels(attributes);
+
+        if (l.isEmpty()) {
+            ; // no-op
+        } else if (attributes.isEmpty()) {
+            attributes = l;
+        } else {
+            attributes = attributes.appendList(l);
+        }
+        return this;
+    }
+
+    public Annotations prepend(List<Attribute.Compound> l) {
+        attributes = filterSentinels(attributes);
+
+        if (l.isEmpty()) {
+            ; // no-op
+        } else if (attributes.isEmpty()) {
+            attributes = l;
+        } else {
+            attributes = attributes.prependList(l);
+        }
+        return this;
+    }
+
+    private List<Attribute.Compound> filterSentinels(List<Attribute.Compound> a) {
+        return (a == IN_PROGRESS || a == NOT_STARTED)
+                ? List.<Attribute.Compound>nil()
+                : a;
+    }
+
+    private boolean isStarted() {
+        return attributes != NOT_STARTED;
+    }
+
+    private List<Attribute.Compound> getPlaceholders() {
+        List<Attribute.Compound> res = List.<Attribute.Compound>nil();
+        for (Attribute.Compound a : filterSentinels(attributes)) {
+            if (a instanceof Placeholder) {
+                res = res.prepend(a);
+            }
+        }
+        return res.reverse();
+    }
+
+    /*
+     * Replace Placeholders for repeating annotations with their containers
+     */
+    private void complete(Annotate.AnnotateRepeatedContext ctx) {
+        Assert.check(!pendingCompletion());
+        Log log = ctx.log;
+        Env<AttrContext> env = ctx.env;
+        JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+        try {
+
+            if (isEmpty()) {
+                return;
+            }
+
+            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) {
+        Log log = ctx.log;
+
+        // Process repeated annotations
+        Attribute.Compound validRepeated =
+                ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor());
+
+        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);
+            if (manualContainer != null) {
+                log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.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 List<Attribute.Compound> placeholderFor;
+        private Symbol on;
+
+        public Placeholder(List<Attribute.Compound> placeholderFor, Symbol on) {
+            super(Type.noType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
+            this.placeholderFor = placeholderFor;
+            this.on = on;
+        }
+
+        @Override
+        public String toString() {
+            return "<placeholder: " + placeholderFor + " on: " + on + ">";
+        }
+
+        public List<Attribute.Compound> getPlaceholderFor() {
+            return placeholderFor;
+        }
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,11 +103,11 @@
      *  represented as a ClassSymbol.
      */
     public static class Class extends Attribute {
-        public final Type type;
+        public final Type classType;
         public void accept(Visitor v) { v.visitClass(this); }
         public Class(Types types, Type type) {
             super(makeClassType(types, type));
-            this.type = type;
+            this.classType = type;
         }
         static Type makeClassType(Types types, Type type) {
             Type arg = type.isPrimitive()
@@ -118,13 +118,13 @@
                                       types.syms.classType.tsym);
         }
         public String toString() {
-            return type + ".class";
+            return classType + ".class";
         }
         public Type getValue() {
-            return type;
+            return classType;
         }
         public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
-            return v.visitType(type, p);
+            return v.visitType(classType, p);
         }
     }
 
@@ -212,6 +212,12 @@
             super(type);
             this.values = values;
         }
+
+        public Array(Type type, List<Attribute> values) {
+            super(type);
+            this.values = values.toArray(new Attribute[values.size()]);
+        }
+
         public void accept(Visitor v) { v.visitArray(this); }
         public String toString() {
             StringBuilder buf = new StringBuilder();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -70,16 +70,16 @@
      * Returns the result of combining the values in this object with
      * the given annotations.
      */
-    public Lint augment(List<Attribute.Compound> attrs) {
-        return augmentor.augment(this, attrs);
+    public Lint augment(Annotations annots) {
+        return augmentor.augment(this, annots.getAttributes());
     }
 
     /**
      * Returns the result of combining the values in this object with
      * the given annotations and flags.
      */
-    public Lint augment(List<Attribute.Compound> attrs, long flags) {
-        Lint l = augmentor.augment(this, attrs);
+    public Lint augment(Annotations annots, long flags) {
+        Lint l = augmentor.augment(this, annots.getAttributes());
         if ((flags & DEPRECATED) != 0) {
             if (l == this)
                 l = new Lint(this);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Fri Aug 31 10:37:46 2012 +0100
@@ -203,6 +203,9 @@
     public boolean allowEffectivelyFinalInInnerClasses() {
         return compareTo(JDK1_8) >= 0;
     }
+    public boolean allowRepeatedAnnotations() {
+        return compareTo(JDK1_8) >= 0;
+    }
     public static SourceVersion toSourceVersion(Source source) {
         switch(source) {
         case JDK1_2:
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Aug 31 10:37:46 2012 +0100
@@ -72,22 +72,24 @@
      */
     public long flags() { return flags_field; }
 
-    /** The attributes of this symbol.
+    /** The attributes of this symbol are contained in this
+     * Annotations. The Annotations instance is NOT immutable.
      */
-    public List<Attribute.Compound> attributes_field;
+    public final Annotations annotations = new Annotations(this);
 
     /** An accessor method for the 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.Compound> getAnnotationMirrors() {
-        return Assert.checkNonNull(attributes_field);
+        return Assert.checkNonNull(annotations.getAttributes());
     }
 
     /** Fetch a particular annotation from a symbol. */
     public Attribute.Compound attribute(Symbol anno) {
-        for (Attribute.Compound a : getAnnotationMirrors())
+        for (Attribute.Compound a : getAnnotationMirrors()) {
             if (a.type.tsym == anno) return a;
+        }
         return null;
     }
 
@@ -120,7 +122,6 @@
         this.owner = owner;
         this.completer = null;
         this.erasure_field = null;
-        this.attributes_field = List.nil();
         this.name = name;
     }
 
@@ -657,10 +658,11 @@
             if (completer != null) complete();
             if (package_info != null && package_info.completer != null) {
                 package_info.complete();
-                if (attributes_field.isEmpty())
-                    attributes_field = package_info.attributes_field;
+                if (annotations.isEmpty()) {
+                    annotations.setAttributes(package_info.annotations);
             }
-            return Assert.checkNonNull(attributes_field);
+            }
+            return Assert.checkNonNull(annotations.getAttributes());
         }
 
         /** A package "exists" if a type or package that exists has
@@ -762,7 +764,7 @@
 
         public List<Attribute.Compound> getAnnotationMirrors() {
             if (completer != null) complete();
-            return Assert.checkNonNull(attributes_field);
+            return Assert.checkNonNull(annotations.getAttributes());
         }
 
         public Type erasure(Types types) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Aug 31 10:37:46 2012 +0100
@@ -156,6 +156,10 @@
     public final Type systemType;
     public final Type autoCloseableType;
     public final Type trustMeType;
+    public final Type containedByType;
+    public final Type containerForType;
+    public final Type documentedType;
+    public final Type elementTypeType;
 
     /** The symbol representing the length field of an array.
      */
@@ -468,6 +472,10 @@
         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");
+        documentedType = enterClass("java.lang.annotation.Documented");
+        elementTypeType = enterClass("java.lang.annotation.ElementType");
         systemType = enterClass("java.lang.System");
         autoCloseableType = enterClass("java.lang.AutoCloseable");
         autoCloseableClose = new MethodSymbol(PUBLIC,
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1358,6 +1358,20 @@
         }
         return result;
     }
+
+    /**
+     * Returns an ArrayType with the component type t
+     *
+     * @param t The component type of the ArrayType
+     * @return the ArrayType for the given component
+     */
+    public ArrayType makeArrayType(Type t) {
+        if (t.tag == VOID ||
+            t.tag >= PACKAGE) {
+            Assert.error("Type t must not be a a VOID or PACKAGE type, " + t.toString());
+        }
+        return new ArrayType(t, syms.arrayClass);
+    }
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="asSuper">
@@ -3811,8 +3825,12 @@
     // <editor-fold defaultstate="collapsed" desc="Annotation support">
 
     public RetentionPolicy getRetention(Attribute.Compound a) {
+        return getRetention(a.type.tsym);
+    }
+
+    public RetentionPolicy getRetention(Symbol sym) {
         RetentionPolicy vis = RetentionPolicy.CLASS; // the default
-        Attribute.Compound c = a.type.tsym.attribute(syms.retentionType.tsym);
+        Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
         if (c != null) {
             Attribute value = c.member(names.value);
             if (value != null && value instanceof Attribute.Enum) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,11 @@
 
 package com.sun.tools.javac.comp;
 
+import java.util.Map;
+import java.util.Objects;
+
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.*;
@@ -83,8 +87,9 @@
     private int enterCount = 0;
 
     ListBuffer<Annotator> q = new ListBuffer<Annotator>();
+    ListBuffer<Annotator> repeatedQ = new ListBuffer<Annotator>();
 
-    public void later(Annotator a) {
+    public void normal(Annotator a) {
         q.append(a);
     }
 
@@ -92,6 +97,10 @@
         q.prepend(a);
     }
 
+    public void repeated(Annotator a) {
+        repeatedQ.append(a);
+    }
+
     /** Called when the Enter phase starts. */
     public void enterStart() {
         enterCount++;
@@ -109,6 +118,10 @@
         try {
             while (q.nonEmpty())
                 q.next().enterAnnotation();
+
+            while (repeatedQ.nonEmpty()) {
+                repeatedQ.next().enterAnnotation();
+            }
         } finally {
             enterCount--;
         }
@@ -124,6 +137,53 @@
         String toString();
     }
 
+    /**
+     * This context contains all the information needed to synthesize new
+     * annotations trees by the completer for repeating annotations.
+     */
+    public class AnnotateRepeatedContext {
+        public final Env<AttrContext> env;
+        public final Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated;
+        public final Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos;
+        public final Log log;
+
+        public AnnotateRepeatedContext(Env<AttrContext> env,
+                                       Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated,
+                                       Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos,
+                                       Log log) {
+            Objects.requireNonNull(env);
+            Objects.requireNonNull(annotated);
+            Objects.requireNonNull(pos);
+            Objects.requireNonNull(log);
+
+            this.env = env;
+            this.annotated = annotated;
+            this.pos = pos;
+            this.log = log;
+        }
+
+        /**
+         * Process a list of repeating annotations returning a new
+         * Attribute.Compound that is the attribute for the synthesized tree
+         * for the container.
+         *
+         * @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) {
+            return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this);
+        }
+
+        /**
+         * Queue the Annotator a on the repeating annotations queue of the
+         * Annotate instance this context belongs to.
+         *
+         * @param a the Annotator to enqueue for repeating annotation annotating
+         */
+        public void annotateRepeated(Annotator a) {
+            Annotate.this.repeated(a);
+        }
+    }
 
 /* ********************************************************************
  * Compute an attribute from its annotation.
@@ -268,4 +328,219 @@
             log.error(tree.pos(), "annotation.value.not.allowable.type");
         return new Attribute.Error(attr.attribExpr(tree, env, expected));
     }
+
+    /* *********************************
+     * Support for repeating annotations
+     ***********************************/
+
+    /* Process repeated annotations. This method returns the
+     * 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) {
+        Attribute.Compound firstOccurrence = annotations.head;
+        List<Attribute> repeated = List.nil();
+        Type origAnnoType;
+        Type arrayOfOrigAnnoType = null;
+        Type targetContainerType = null;
+        MethodSymbol containerValueSymbol = null;
+
+        Assert.check(!annotations.isEmpty() &&
+                     !annotations.tail.isEmpty()); // i.e. size() > 1
+
+        for (List<Attribute.Compound> al = annotations;
+             !al.isEmpty();
+             al = al.tail)
+        {
+            Attribute.Compound currentAnno = al.head;
+
+            origAnnoType = currentAnno.type;
+            if (arrayOfOrigAnnoType == null) {
+                arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
 }
+
+            Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno));
+            if (currentContainerType == null) {
+                continue;
+            }
+            // Assert that the target Container is == for all repeated
+            // annos of the same annotation type, the types should
+            // come from the same Symbol, i.e. be '=='
+            Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
+            targetContainerType = currentContainerType;
+
+            containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));
+
+            if (containerValueSymbol == null) { // Check of CA type failed
+                // errors are already reported
+                continue;
+            }
+
+            repeated = repeated.prepend(currentAnno);
+        }
+
+        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)));
+            Attribute.Compound c = enterAnnotation(annoTree,
+                                                   targetContainerType,
+                                                   ctx.env);
+            return c;
+        } else {
+            return null; // errors should have been reported elsewhere
+        }
+    }
+
+    /** Fetches the actual Type that should be the containing annotation. */
+    private Type getContainingType(Attribute.Compound currentAnno,
+            DiagnosticPosition pos)
+    {
+        Type origAnnoType = currentAnno.type;
+        TypeSymbol origAnnoDecl = origAnnoType.tsym;
+
+        // Fetch the ContainedBy 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);
+            return null;
+        }
+
+        return filterSame(extractContainingType(ca, pos, origAnnoDecl),
+                          origAnnoType);
+    }
+
+    // returns null if t is same as 's', returns 't' otherwise
+    private Type filterSame(Type t, Type s) {
+        if (t == null || s == null) {
+            return t;
+        }
+
+        return types.isSameType(t, s) ? null : t;
+    }
+
+    /** Extract the actual Type to be used for a containing annotation. */
+    private Type extractContainingType(Attribute.Compound ca,
+            DiagnosticPosition pos,
+            TypeSymbol annoDecl)
+    {
+        // The next three checks check that the ContainedBy annotation
+        // on the declaration of the annotation type that is repeating is
+        // valid.
+
+        // ContainedBy must have at least one element
+        if (ca.values.isEmpty()) {
+            log.error(pos, "invalid.containedby.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);
+            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);
+            return null;
+        }
+
+        return ((Attribute.Class)p.snd).getValue();
+    }
+
+    /* Validate that the suggested targetContainerType Type is a valid
+     * container type for repeated instances of originalAnnoType
+     * annotations. Return null and report errors if this is not the
+     * case, return the MethodSymbol of the value element in
+     * targetContainerType if it is suitable (this is needed to
+     * synthesize the container). */
+    private MethodSymbol validateContainer(Type targetContainerType,
+                                           Type originalAnnoType,
+                                           DiagnosticPosition pos) {
+        MethodSymbol containerValueSymbol = null;
+        boolean fatalError = false;
+
+        // Validate that there is a (and only 1) value method
+        Scope scope = targetContainerType.tsym.members();
+        int nr_value_elems = 0;
+        boolean error = false;
+        for(Symbol elm : scope.getElementsByName(names.value)) {
+            nr_value_elems++;
+
+            if (nr_value_elems == 1 &&
+                elm.kind == Kinds.MTH) {
+                containerValueSymbol = (MethodSymbol)elm;
+            } else {
+                error = true;
+            }
+        }
+        if (error) {
+            log.error(pos,
+                      "invalid.containedby.annotation.multiple.values",
+                      targetContainerType,
+                      nr_value_elems);
+            return null;
+        } else if (nr_value_elems == 0) {
+            log.error(pos,
+                      "invalid.containedby.annotation.no.value",
+                      targetContainerType);
+            return null;
+        }
+
+        // validate that the 'value' element is a method
+        // probably "impossible" to fail this
+        if (containerValueSymbol.kind != Kinds.MTH) {
+            log.error(pos,
+                      "invalid.containedby.annotation.invalid.value",
+                      targetContainerType);
+            fatalError = true;
+        }
+
+        // validate that the 'value' element has the correct return type
+        // i.e. array of original anno
+        Type valueRetType = containerValueSymbol.type.getReturnType();
+        Type expectedType = types.makeArrayType(originalAnnoType);
+        if (!(types.isArray(valueRetType) &&
+              types.isSameType(expectedType, valueRetType))) {
+            log.error(pos,
+                      "invalid.containedby.annotation.value.return",
+                      targetContainerType,
+                      valueRetType,
+                      expectedType);
+            fatalError = true;
+        }
+
+        // validate that all other elements of containing type has defaults
+        scope = targetContainerType.tsym.members();
+        error = false;
+        for(Symbol elm : scope.getElements()) {
+            if (elm.name != names.value &&
+                elm.kind == Kinds.MTH &&
+                ((MethodSymbol)elm).defaultValue == null) {
+                log.error(pos,
+                          "invalid.containedby.annotation.elem.nondefault",
+                          targetContainerType,
+                          elm);
+                containerValueSymbol = null;
+                error = true;
+            }
+        }
+        if (error) {
+            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
+        // in Check.validateRepeatedAnnotaton();
+
+        return fatalError ? null : containerValueSymbol;
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Aug 31 10:37:46 2012 +0100
@@ -662,10 +662,12 @@
         // env.info.enclVar.attributes_field might not yet have been evaluated, and so might be
         // null. In that case, calling augment will throw an NPE. To avoid this, for now we
         // revert to the jdk 6 behavior and ignore the (unevaluated) attributes.
-        if (env.info.enclVar.attributes_field == null)
+        if (env.info.enclVar.annotations.pendingCompletion()) {
             env.info.lint = lintEnv.info.lint;
-        else
-            env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags());
+        } else {
+            env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.annotations,
+                                                      env.info.enclVar.flags());
+        }
 
         Lint prevLint = chk.setLint(env.info.lint);
         JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
@@ -776,7 +778,7 @@
     public void visitMethodDef(JCMethodDecl tree) {
         MethodSymbol m = tree.sym;
 
-        Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
+        Lint lint = env.info.lint.augment(m.annotations, m.flags());
         Lint prevLint = chk.setLint(lint);
         MethodSymbol prevMethod = chk.setMethod(m);
         try {
@@ -921,7 +923,7 @@
         }
 
         VarSymbol v = tree.sym;
-        Lint lint = env.info.lint.augment(v.attributes_field, v.flags());
+        Lint lint = env.info.lint.augment(v.annotations, v.flags());
         Lint prevLint = chk.setLint(lint);
 
         // Check that the variable's declared type is well-formed.
@@ -3069,7 +3071,7 @@
                 lintEnv = lintEnv.next;
 
             // Having found the enclosing lint value, we can initialize the lint value for this class
-            env.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags());
+            env.info.lint = lintEnv.info.lint.augment(c.annotations, c.flags());
 
             Lint prevLint = chk.setLint(env.info.lint);
             JavaFileObject prev = log.useSource(c.sourcefile);
@@ -3133,6 +3135,26 @@
             if (tree.typarams.nonEmpty())
                 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);
+                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);
+            }
         } else {
             // Check that all extended classes and interfaces
             // are compatible (i.e. no two define methods with same arguments
@@ -3194,6 +3216,16 @@
         }
     }
         // where
+        /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
+        private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
+            for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
+                if (types.isSameType(al.head.annotationType.type, t))
+                    return al.head.pos();
+            }
+
+            return null;
+        }
+
         /** check if a class is a subtype of Serializable, if that is available. */
         private boolean isSerializable(ClassSymbol c) {
             try {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Aug 31 10:37:46 2012 +0100
@@ -69,7 +69,6 @@
     private final Infer infer;
     private final Types types;
     private final JCDiagnostic.Factory diags;
-    private final boolean skipAnnotations;
     private boolean warnOnSyntheticConflicts;
     private boolean suppressAbortOnBadClassFile;
     private boolean enableSunApiLintControl;
@@ -113,7 +112,6 @@
         allowCovariantReturns = source.allowCovariantReturns();
         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
         complexInference = options.isSet("complexinference");
-        skipAnnotations = options.isSet("skipAnnotations");
         warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
         suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
         enableSunApiLintControl = options.isSet("enableSunApiLintControl");
@@ -2422,14 +2420,13 @@
     /** Check the annotations of a symbol.
      */
     public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
-        if (skipAnnotations) return;
         for (JCAnnotation a : annotations)
             validateAnnotation(a, s);
     }
 
     /** Check an annotation of a symbol.
      */
-    public void validateAnnotation(JCAnnotation a, Symbol s) {
+    private void validateAnnotation(JCAnnotation a, Symbol s) {
         validateAnnotationTree(a);
 
         if (!annotationApplicable(a, s))
@@ -2441,6 +2438,215 @@
         }
     }
 
+    /**
+     * Validate the proposed container 'containedBy' on the
+     * annotation type symbol 's'. Report errors at position
+     * 'pos'.
+     *
+     * @param s The (annotation)type declaration annotated with a @ContainedBy
+     * @param containerAnno the @ContainedBy 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));
+
+        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", s, containedBy);
+            return;
+        }
+
+        validateHasContainerFor(t.tsym, s, pos);
+        validateRetention(t.tsym, s, pos);
+        validateDocumented(t.tsym, s, pos);
+        validateInherited(t.tsym, s, pos);
+        validateTarget(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();
+        }
+
+        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) {
+        Attribute.RetentionPolicy containerRetention = types.getRetention(container);
+        Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
+
+        boolean error = false;
+        switch (containedRetention) {
+        case RUNTIME:
+            if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
+                error = true;
+            }
+            break;
+        case CLASS:
+            if (containerRetention == Attribute.RetentionPolicy.SOURCE)  {
+                error = true;
+            }
+        }
+        if (error ) {
+            log.error(pos, "invalid.containedby.annotation.retention",
+                      container, containerRetention,
+                      contained, containedRetention);
+        }
+    }
+
+    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);
+            }
+        }
+    }
+
+    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);
+            }
+        }
+    }
+
+    private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
+        Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
+
+        // If contained has no Target, we are done
+        if (containedTarget == null) {
+            return;
+        }
+
+        // If contained has Target m1, container must have a Target
+        // annotation, m2, and m2 must be a subset of m1. (This is
+        // trivially true if contained has no target as per above).
+
+        // 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);
+            return;
+        }
+
+        Set<Name> containerTargets = new HashSet<Name>();
+        for (Attribute app : containerTarget.values) {
+            if (!(app instanceof Attribute.Enum)) {
+                continue; // recovery
+            }
+            Attribute.Enum e = (Attribute.Enum)app;
+            containerTargets.add(e.value.name);
+        }
+
+        Set<Name> containedTargets = new HashSet<Name>();
+        for (Attribute app : containedTarget.values) {
+            if (!(app instanceof Attribute.Enum)) {
+                continue; // recovery
+            }
+            Attribute.Enum e = (Attribute.Enum)app;
+            containedTargets.add(e.value.name);
+        }
+
+        if (!isTargetSubset(containedTargets, containerTargets)) {
+            log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+        }
+    }
+
+    /** Checks that t is a subset of s, with respect to ElementType
+     * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}
+     */
+    private boolean isTargetSubset(Set<Name> s, Set<Name> t) {
+        // Check that all elements in t are present in s
+        for (Name n2 : t) {
+            boolean currentElementOk = false;
+            for (Name n1 : s) {
+                if (n1 == n2) {
+                    currentElementOk = true;
+                    break;
+                } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
+                    currentElementOk = true;
+                    break;
+                }
+            }
+            if (!currentElementOk)
+                return false;
+        }
+        return true;
+    }
+
     /** Is s a method symbol that overrides a method in a superclass? */
     boolean isOverrider(Symbol s) {
         if (s.kind != MTH || s.isStatic())
@@ -2461,12 +2667,10 @@
 
     /** Is the annotation applicable to the symbol? */
     boolean annotationApplicable(JCAnnotation a, Symbol s) {
-        Attribute.Compound atTarget =
-            a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
-        if (atTarget == null) return true;
-        Attribute atValue = atTarget.member(names.value);
-        if (!(atValue instanceof Attribute.Array)) return true; // error recovery
-        Attribute.Array arr = (Attribute.Array) atValue;
+        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
+        if (arr == null) {
+            return true;
+        }
         for (Attribute app : arr.values) {
             if (!(app instanceof Attribute.Enum)) return true; // recovery
             Attribute.Enum e = (Attribute.Enum) app;
@@ -2508,6 +2712,16 @@
         return false;
     }
 
+
+    Attribute.Array getAttributeTargetAttribute(Symbol s) {
+        Attribute.Compound atTarget =
+            s.attribute(syms.annotationTargetType.tsym);
+        if (atTarget == null) return null; // ok, is applicable
+        Attribute atValue = atTarget.member(names.value);
+        if (!(atValue instanceof Attribute.Array)) return null; // error recovery
+        return (Attribute.Array) atValue;
+    }
+
     /** Check an annotation value.
      */
     public void validateAnnotation(JCAnnotation a) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Fri Aug 31 10:37:46 2012 +0100
@@ -157,7 +157,7 @@
         Env<AttrContext> lintEnv = localEnv;
         while (lintEnv.info.lint == null)
             lintEnv = lintEnv.next;
-        localEnv.info.lint = lintEnv.info.lint.augment(sym.attributes_field, sym.flags());
+        localEnv.info.lint = lintEnv.info.lint.augment(sym.annotations, sym.flags());
         return localEnv;
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java	Fri Aug 31 10:37:46 2012 +0100
@@ -406,7 +406,7 @@
             Lint lintPrev = lint;
 
             pendingExits = new ListBuffer<PendingExit>();
-            lint = lint.augment(tree.sym.attributes_field);
+            lint = lint.augment(tree.sym.annotations);
 
             try {
                 // process all the static initializers
@@ -442,7 +442,7 @@
             if (tree.body == null) return;
             Lint lintPrev = lint;
 
-            lint = lint.augment(tree.sym.attributes_field);
+            lint = lint.augment(tree.sym.annotations);
 
             Assert.check(pendingExits.isEmpty());
 
@@ -468,7 +468,7 @@
         public void visitVarDef(JCVariableDecl tree) {
             if (tree.init != null) {
                 Lint lintPrev = lint;
-                lint = lint.augment(tree.sym.attributes_field);
+                lint = lint.augment(tree.sym.annotations);
                 try{
                     scan(tree.init);
                 } finally {
@@ -783,7 +783,7 @@
             }
             classDef = tree;
             thrown = List.nil();
-            lint = lint.augment(tree.sym.attributes_field);
+            lint = lint.augment(tree.sym.annotations);
 
             try {
                 // process all the static initializers
@@ -863,7 +863,7 @@
             List<Type> mthrown = tree.sym.type.getThrownTypes();
             Lint lintPrev = lint;
 
-            lint = lint.augment(tree.sym.attributes_field);
+            lint = lint.augment(tree.sym.annotations);
 
             Assert.check(pendingExits.isEmpty());
 
@@ -902,7 +902,7 @@
         public void visitVarDef(JCVariableDecl tree) {
             if (tree.init != null) {
                 Lint lintPrev = lint;
-                lint = lint.augment(tree.sym.attributes_field);
+                lint = lint.augment(tree.sym.annotations);
                 try{
                     scan(tree.init);
                 } finally {
@@ -1491,7 +1491,7 @@
                 firstadr = nextadr;
             }
             classDef = tree;
-            lint = lint.augment(tree.sym.attributes_field);
+            lint = lint.augment(tree.sym.annotations);
 
             try {
                 // define all the static fields
@@ -1558,7 +1558,7 @@
             int firstadrPrev = firstadr;
             Lint lintPrev = lint;
 
-            lint = lint.augment(tree.sym.attributes_field);
+            lint = lint.augment(tree.sym.annotations);
 
             Assert.check(pendingExits.isEmpty());
 
@@ -1609,7 +1609,7 @@
             if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
             if (tree.init != null) {
                 Lint lintPrev = lint;
-                lint = lint.augment(tree.sym.attributes_field);
+                lint = lint.augment(tree.sym.annotations);
                 try{
                     scanExpr(tree.init);
                     if (track) letInit(tree.pos(), tree.sym);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Aug 31 10:37:46 2012 +0100
@@ -2257,7 +2257,7 @@
                                 null, List.<JCExpression>nil(), List.<JCTree>nil());
             ClassSymbol c = tree.packge.package_info;
             c.flags_field |= flags;
-            c.attributes_field = tree.packge.attributes_field;
+            c.annotations.setAttributes(tree.packge.annotations);
             ClassType ctype = (ClassType) c.type;
             ctype.supertype_field = syms.objectType;
             ctype.interfaces_field = List.nil();
@@ -2274,7 +2274,8 @@
             case LEGACY:
                 return tree.packageAnnotations.nonEmpty();
             case NONEMPTY:
-                for (Attribute.Compound a: tree.packge.attributes_field) {
+                for (Attribute.Compound a :
+                         tree.packge.annotations.getAttributes()) {
                     Attribute.RetentionPolicy p = types.getRetention(a);
                     if (p != Attribute.RetentionPolicy.SOURCE)
                         return true;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Aug 31 10:37:46 2012 +0100
@@ -76,11 +76,10 @@
     private final Annotate annotate;
     private final Types types;
     private final JCDiagnostic.Factory diags;
+    private final Source source;
     private final Target target;
     private final DeferredLintHandler deferredLintHandler;
 
-    private final boolean skipAnnotations;
-
     public static MemberEnter instance(Context context) {
         MemberEnter instance = context.get(memberEnterKey);
         if (instance == null)
@@ -102,10 +101,9 @@
         annotate = Annotate.instance(context);
         types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
+        source = Source.instance(context);
         target = Target.instance(context);
         deferredLintHandler = DeferredLintHandler.instance(context);
-        Options options = Options.instance(context);
-        skipAnnotations = options.isSet("skipAnnotations");
     }
 
     /** A queue for classes whose members still need to be entered into the
@@ -690,7 +688,7 @@
 
     public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
         Env<AttrContext> mEnv = methodEnv(tree, env);
-        mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags());
+        mEnv.info.lint = mEnv.info.lint.augment(tree.sym.annotations, tree.sym.flags());
         for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
             mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
         for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
@@ -727,18 +725,24 @@
     void annotateLater(final List<JCAnnotation> annotations,
                        final Env<AttrContext> localEnv,
                        final Symbol s) {
-        if (annotations.isEmpty()) return;
-        if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now
-        annotate.later(new Annotate.Annotator() {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        if (s.kind != PCK) {
+            s.annotations.reset(); // mark Annotations as incomplete for now
+        }
+        annotate.normal(new Annotate.Annotator() {
+                @Override
                 public String toString() {
                     return "annotate " + annotations + " onto " + s + " in " + s.owner;
                 }
+
+                @Override
                 public void enterAnnotation() {
-                    Assert.check(s.kind == PCK || s.attributes_field == null);
+                    Assert.check(s.kind == PCK || s.annotations.pendingCompletion());
                     JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
                     try {
-                        if (s.attributes_field != null &&
-                            s.attributes_field.nonEmpty() &&
+                        if (!s.annotations.isEmpty() &&
                             annotations.nonEmpty())
                             log.error(annotations.head.pos,
                                       "already.annotated",
@@ -756,7 +760,7 @@
      * java.lang.Deprecated.
      **/
     private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
-        for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+        for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
             JCAnnotation a = al.head;
             if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
                 return true;
@@ -764,42 +768,62 @@
         return false;
     }
 
-
     /** Enter a set of annotations. */
     private void enterAnnotations(List<JCAnnotation> annotations,
                           Env<AttrContext> env,
                           Symbol s) {
-        ListBuffer<Attribute.Compound> buf =
-            new ListBuffer<Attribute.Compound>();
-        Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
-        if (!skipAnnotations)
-        for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+        Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
+                new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>();
+        Map<Attribute.Compound, DiagnosticPosition> pos =
+                new HashMap<Attribute.Compound, DiagnosticPosition>();
+
+        for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
             JCAnnotation a = al.head;
             Attribute.Compound c = annotate.enterAnnotation(a,
                                                             syms.annotationType,
                                                             env);
-            if (c == null) continue;
-            buf.append(c);
+            if (c == null) {
+                continue;
+            }
+
+            if (annotated.containsKey(a.type.tsym)) {
+                if (source.allowRepeatedAnnotations()) {
+                    ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym);
+                    l = l.append(c);
+                    annotated.put(a.type.tsym, l);
+                    pos.put(c, a.pos());
+                } else {
+                    log.error(a.pos(), "duplicate.annotation");
+                }
+            } else {
+                annotated.put(a.type.tsym, ListBuffer.of(c));
+                pos.put(c, a.pos());
+            }
+
             // Note: @Deprecated has no effect on local variables and parameters
             if (!c.type.isErroneous()
                 && s.owner.kind != MTH
-                && types.isSameType(c.type, syms.deprecatedType))
+                && types.isSameType(c.type, syms.deprecatedType)) {
                 s.flags_field |= Flags.DEPRECATED;
-            if (!annotated.add(a.type.tsym))
-                log.error(a.pos, "duplicate.annotation");
+        }
         }
-        s.attributes_field = buf.toList();
+
+        s.annotations.setAttributesWithCompletion(
+                annotate.new AnnotateRepeatedContext(env, annotated, pos, log));
     }
 
     /** Queue processing of an attribute default value. */
     void annotateDefaultValueLater(final JCExpression defaultValue,
                                    final Env<AttrContext> localEnv,
                                    final MethodSymbol m) {
-        annotate.later(new Annotate.Annotator() {
+        annotate.normal(new Annotate.Annotator() {
+                @Override
                 public String toString() {
                     return "annotate " + m.owner + "." +
                         m + " default " + defaultValue;
                 }
+
+                @Override
                 public void enterAnnotation() {
                     JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
                     try {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1321,7 +1321,7 @@
                 else
                     proxies.append(proxy);
             }
-            annotate.later(new AnnotationCompleter(sym, proxies.toList()));
+            annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
         }
     }
 
@@ -1347,7 +1347,7 @@
     void attachAnnotationDefault(final Symbol sym) {
         final MethodSymbol meth = (MethodSymbol)sym; // only on methods
         final Attribute value = readAttributeValue();
-        annotate.later(new AnnotationDefaultCompleter(meth, value));
+        annotate.normal(new AnnotationDefaultCompleter(meth, value));
     }
 
     Type readTypeOrClassSymbol(int i) {
@@ -1693,10 +1693,13 @@
             JavaFileObject previousClassFile = currentClassFile;
             try {
                 currentClassFile = classFile;
+                Annotations annotations = sym.annotations;
                 List<Attribute.Compound> newList = deproxyCompoundList(l);
-                sym.attributes_field = ((sym.attributes_field == null)
-                                        ? newList
-                                        : newList.prependList(sym.attributes_field));
+                if (annotations.pendingCompletion()) {
+                    annotations.setAttributes(newList);
+                } else {
+                    annotations.append(newList);
+                }
             } finally {
                 currentClassFile = previousClassFile;
             }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Aug 31 10:37:46 2012 +0100
@@ -825,7 +825,7 @@
         }
         public void visitClass(Attribute.Class clazz) {
             databuf.appendByte('c');
-            databuf.appendChar(pool.put(typeSig(clazz.type)));
+            databuf.appendChar(pool.put(typeSig(clazz.classType)));
         }
         public void visitCompound(Attribute.Compound compound) {
             databuf.appendByte('@');
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java	Fri Aug 31 10:37:46 2012 +0100
@@ -157,7 +157,7 @@
         if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
             return false;
 
-        for (Attribute.Compound a: c.attributes_field) {
+        for (Attribute.Compound a: c.annotations.getAttributes()) {
             if (a.type.tsym == syms.nativeHeaderType.tsym)
                 return true;
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -177,7 +177,7 @@
         }
 
         public void visitClass(Attribute.Class c) {
-            value = new MirroredTypeExceptionProxy(c.type);
+            value = new MirroredTypeExceptionProxy(c.classType);
         }
 
         public void visitArray(Attribute.Array a) {
@@ -187,7 +187,7 @@
                 // Construct a proxy for a MirroredTypesException
                 ListBuffer<TypeMirror> elems = new ListBuffer<TypeMirror>();
                 for (Attribute value : a.values) {
-                    Type elem = ((Attribute.Class) value).type;
+                    Type elem = ((Attribute.Class) value).classType;
                     elems.append(elem);
                 }
                 value = new MirroredTypesExceptionProxy(elems.toList());
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Aug 31 10:37:46 2012 +0100
@@ -250,6 +250,70 @@
 compiler.err.duplicate.annotation.member.value=\
     duplicate annotation member value {0} in {1}
 
+# 0: type
+compiler.err.duplicate.annotation.missing.container=\
+    duplicate annotation, the declaration of {0} does not have a ContainedBy annotation
+
+# 0: type, 1: type
+compiler.err.invalid.container.no.containedby=\
+    invalid contained repeatable annotation, {0} is not annotated with {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.wrong.containedby=\
+    invalid contained repeatable annotation, {0} does not match {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.no.containerfor=\
+    invalid container for repeating annotations, {0} is not annotated with {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.wrong.containerfor=\
+    invalid container for repeating annotations, {0} does not match {1}
+
+# 0: type
+compiler.err.invalid.containedby.annotation=\
+    duplicate annotation, {0} is annotated with an invalid ContainedBy annotation
+
+# 0: type
+compiler.err.invalid.containedby.annotation.no.value=\
+    duplicate annotation, {0} is not a valid ContainedBy, no value element method declared
+
+# 0: type, 1: number
+compiler.err.invalid.containedby.annotation.multiple.values=\
+    duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared
+
+# 0: type
+compiler.err.invalid.containedby.annotation.invalid.value=\
+    duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method
+
+# 0: type, 1: type, 2: type
+compiler.err.invalid.containedby.annotation.value.return=\
+    duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
+
+# 0: type, 1: symbol
+compiler.err.invalid.containedby.annotation.elem.nondefault=\
+    duplicate annotation, element {1} in containing annotation {0} does not have a default value
+
+# 0: symbol, 1: type, 2: symbol, 3: type
+compiler.err.invalid.containedby.annotation.retention=\
+    containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3}
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.not.documented=\
+    containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.not.inherited=\
+    containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.incompatible.target=\
+    target of container annotation {0} is not a subset of target of repeated annotation {1}
+
+# 0: symbol
+compiler.err.invalid.containedby.annotation.repeated.and.container.present=\
+    container {0} must not be present at the same time as the element it contains
+
 # 0: name
 compiler.err.duplicate.class=\
     duplicate class: {0}
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -206,9 +206,7 @@
             }
             ClassSymbol cs = (ClassSymbol) sym;
             if (addLegacyAnnotation) {
-                cs.attributes_field = (cs.attributes_field == null)
-                    ? List.of(proprietary)
-                    : cs.attributes_field.prepend(proprietary);
+                cs.annotations.prepend(List.of(proprietary));
             }
             writeClass(pool, cs, writer);
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -740,7 +740,7 @@
             result = Literal(v.value);
         }
         public void visitClass(Attribute.Class clazz) {
-            result = ClassLiteral(clazz.type).setType(syms.classType);
+            result = ClassLiteral(clazz.classType).setType(syms.classType);
         }
         public void visitEnum(Attribute.Enum e) {
             result = QualIdent(e.value);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -83,7 +83,7 @@
 
         public void visitClass(Attribute.Class c) {
             value = TypeMaker.getType(env,
-                                      env.types.erasure(c.type));
+                                      env.types.erasure(c.classType));
         }
 
         public void visitEnum(Attribute.Enum e) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean BasicRepeatingAnnotations BasicRepeatingAnnos BasicNonRepeatingAnno Foo Foos Bar
+ * @run compile BasicRepeatingAnnotations.java
+ * @run main BasicRepeatingAnnotations
+ */
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Foos {
+    Foo[] value();
+}
+
+@interface Bar {}
+
+@Foo @Foo
+@Foo
+@Bar
+@Foo
+@Foo
+@Foo
+@Foo
+@Foo @Foo
+@Foo
+class BasicRepeatingAnnos {}
+
+@Foo
+class BasicNonRepeatingAnno {}
+
+public class BasicRepeatingAnnotations {
+    public static void main(String[] args) throws Exception {
+        Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class);
+        if (a == null) {
+            throw new RuntimeException("Container annotation missing");
+        }
+
+        // verify that container not present on nonrepeating
+        a = BasicNonRepeatingAnno.class.getAnnotation(Foos.class);
+        if (a != null) {
+            throw new RuntimeException("Container annotation present");
+        }
+        a = BasicNonRepeatingAnno.class.getAnnotation(Foo.class);
+        if (a == null) {
+            throw new RuntimeException("Repeated annoation not directly present");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Foos Foo Bars Bar Baz Bazs CheckTargets
+ * @run compile CheckTargets.java
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@Target(ElementType.TYPE)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Target(ElementType.ANNOTATION_TYPE)
+@interface Foos {
+    Foo[] value();
+}
+
+@ContainedBy(Bars.class)
+@Target(ElementType.TYPE)
+@interface Bar {}
+
+@ContainerFor(Bar.class)
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
+@interface Bars {
+    Bar[] value();
+}
+
+
+@ContainedBy(Bazs.class)
+@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+@interface Baz {}
+
+@ContainerFor(Baz.class)
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
+@interface Bazs {
+    Baz[] value();
+}
+
+
+public class CheckTargets {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Bar BarContainer ContainerHasRepeatedContained
+ * @run compile ContainerHasRepeatedContained.java
+ */
+
+import java.lang.annotation.ContainedBy;
+import java.lang.annotation.ContainerFor;
+
+@ContainedBy(BarContainer.class)
+@interface Bar {}
+
+@Bar
+@Bar
+@ContainerFor(Bar.class)
+@interface BarContainer {
+    Bar[] value();
+}
+
+public class ContainerHasRepeatedContained {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean DelayRepeatedContainer Bar BarContainer
+ * @run compile DelayRepeatedContainer.java
+ */
+
+import java.lang.annotation.*;
+
+public class DelayRepeatedContainer {
+    @Bar("apa") @Bar("banan")
+    String meh() { return "meh"; }
+}
+
+@Bar("katt")
+@Bar("lol")
+@ContainedBy(BarContainer.class)
+@interface Bar {
+    String value();
+}
+
+@ContainerFor(Bar.class)
+@interface BarContainer {
+    Bar[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Foos Foo
+ * @run compile/fail InvalidTarget.java
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@Target(ElementType.ANNOTATION_TYPE)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Target(ElementType.TYPE)
+@interface Foos {
+    Foo[] value();
+}
+
+public class InvalidTargets {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail MissingContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+
+@ContainerFor(MissingContainedBy.class)
+@interface Foos {
+    MissingContainedBy[] value();
+}
+
+public @interface MissingContainedBy {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail MissingContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@interface Foos {
+    MissingContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface MissingContainerFor {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean NestedContainers BasicRepeatingAnnos BasicRepeatingAnnos2 Foo Foos FoosFoos
+ * @run compile NestedContainers.java
+ * @run main NestedContainers
+ */
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(FoosFoos.class)
+@ContainerFor(Foo.class)
+@interface Foos {
+    Foo[] value();
+}
+
+@ContainerFor(Foos.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface FoosFoos {
+    Foos[] value();
+}
+
+@Foo
+@Foo
+class BasicRepeatingAnnos {}
+
+@Foos({})
+@Foos({})
+class BasicRepeatingAnnos2 {}
+
+public class NestedContainers {
+    public static void main(String[] args) throws Exception {
+        Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class);
+        if (a == null) {
+            throw new RuntimeException("Container annotation missing");
+        }
+
+        // Check 2:nd level container
+        a = BasicRepeatingAnnos2.class.getAnnotation(FoosFoos.class);
+        if (a == null) {
+            throw new RuntimeException("Container annotation missing");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean RepMemberAnno Bar BarContainer
+ * @run compile RepMemberAnno.java
+ */
+
+import java.lang.annotation.ContainedBy;
+import java.lang.annotation.ContainerFor;
+
+public class RepMemberAnno {
+    @Bar("Apa") @Bar("Banan")
+    public void meh() {}
+}
+
+@ContainedBy(BarContainer.class)
+@interface Bar {
+    String value();
+}
+
+@ContainerFor(Bar.class)
+@interface BarContainer {
+    Bar[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean RepSelfMemberAnno BarContainer BarContainerContainer
+ * @run compile RepSelfMemberAnno.java
+ */
+
+import java.lang.annotation.*;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(BarContainer.class)
+public @interface RepSelfMemberAnno {
+    @RepSelfMemberAnno @RepSelfMemberAnno
+    String meh() default "banan";
+}
+
+
+@ContainedBy(BarContainerContainer.class)
+@Retention(RetentionPolicy.RUNTIME)
+@ContainerFor(RepSelfMemberAnno.class)
+@interface BarContainer {
+    RepSelfMemberAnno[] value();
+}
+
+@ContainerFor(BarContainer.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface BarContainerContainer {
+    BarContainer[] value();
+    String meh() default "apa";
+}
+
+@BarContainer(value={})
+@BarContainer(value={})
+@interface Bar {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail RepeatingAndContainerPresent.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@interface Foos {
+    Foo[] value();
+}
+
+
+@Foo
+@Foo
+@Foos({})
+public class RepeatingAndContainerPresent {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean SelfRepeatingAnnotations Foos SelfRepeatingAnno
+ * @run compile SelfRepeatingAnnotations.java
+ * @run main SelfRepeatingAnnotations
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(SelfRepeatingAnno.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Foos {
+    SelfRepeatingAnno[] value();
+}
+
+@SelfRepeatingAnno
+@Retention(RetentionPolicy.RUNTIME)
+@SelfRepeatingAnno
+@ContainedBy(Foos.class)
+@interface SelfRepeatingAnno {}
+
+public class SelfRepeatingAnnotations {
+    public static void  main(String[] args) throws Exception {
+        Annotation a = SelfRepeatingAnno.class.getAnnotation(Foos.class);
+        if (a == null) {
+            throw new RuntimeException("Container annotation missing");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile SingleRepeatingAndContainer.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@interface Foos {
+    Foo[] value();
+}
+
+@Foo
+@Foos({})
+public class SingleRepeatingAndContainer {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(UseWrongContainedBy.class)
+@interface Foos {
+    UseWrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface UseWrongContainedBy {}
+
+@UseWrongContainedBy @UseWrongContainedBy
+@interface Foo {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+    UseWrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface UseWrongContainerFor {}
+
+@UseWrongContainerFor @UseWrongContainerFor
+@interface Foo {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail WrongContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(WrongContainedBy.class)
+@interface Foos {
+    WrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface WrongContainedBy {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail WrongContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+    WrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt	Fri Aug 31 10:37:46 2012 +0100
@@ -5,6 +5,9 @@
 compiler.err.cant.read.file                             # (apt.JavaCompiler?)
 compiler.err.cant.select.static.class.from.param.type
 compiler.err.illegal.char.for.encoding
+compiler.err.invalid.containedby.annotation             # should not happen
+compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen
+compiler.err.invalid.containedby.annotation.multiple.values # can't happen
 compiler.err.io.exception                               # (javah.JavahTask?)
 compiler.err.limit.code                                 # Code
 compiler.err.limit.code.too.large.for.try.stmt          # Gen
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.not.documented
+
+import java.lang.annotation.*;
+
+@Documented
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByDocumentedMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.not.inherited
+
+import java.lang.annotation.*;
+
+@Inherited
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByInheritedMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.no.value
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos {}
+
+@Anno
+@Anno
+class ContainedByNoValue { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.elem.nondefault
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); String foo(); }
+
+@Anno
+@Anno
+class ContainedByNonDefault { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.retention
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByRetentionMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.incompatible.target
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@Target(ElementType.METHOD)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+class ContainedByTargetMismatch { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.value.return
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { String value(); }
+
+@Anno
+@Anno
+class ContainedByWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java	Mon Aug 27 10:59:13 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java	Fri Aug 31 10:37:46 2012 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,8 @@
  */
 
 // key: compiler.err.duplicate.annotation
+// key: compiler.warn.source.no.bootclasspath
+// options: -source 7
 
 @interface Anno { }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.duplicate.annotation.missing.container
+
+@interface Anno { }
+
+@Anno
+@Anno
+class DuplicateAnnotationJava8 { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+@Annos(@Anno)
+class RepeatingAnnotationAndContainer { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WrongContainedBy.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.container.no.containerfor
+// key: compiler.err.invalid.container.wrong.containedby
+
+import java.lang.annotation.*;
+
+@ContainerFor(WrongContainedBy.class)
+@interface Foos {
+    WrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface WrongContainedBy {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WrongContainerFor.java	Fri Aug 31 10:37:46 2012 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.invalid.container.wrong.containerfor
+// key: compiler.err.invalid.container.no.containedby
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+    WrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface WrongContainerFor {}