// This method is part of the javax.lang.model API, do not use this in javac code.
  public <A extends Annotation> A getAnnotation(Class<A> annoType) {

    if (!annoType.isAnnotation())
      throw new IllegalArgumentException("Not an annotation type: " + annoType);

    Attribute.Compound c = getAttribute(annoType);
    return c == null ? null : AnnotationProxyMaker.generateAnnotation(c, annoType);
  }
  // This method is part of the javax.lang.model API, do not use this in javac code.
  public <A extends Annotation> A[] getAnnotationsByType(Class<A> annoType) {

    if (!annoType.isAnnotation())
      throw new IllegalArgumentException("Not an annotation type: " + annoType);
    // If annoType does not declare a container this is equivalent to wrapping
    // getAnnotation(...) in an array.
    Class<? extends Annotation> containerType = getContainer(annoType);
    if (containerType == null) {
      A res = getAnnotation(annoType);
      int size = res == null ? 0 : 1;

      @SuppressWarnings("unchecked") // annoType is the Class for A
      A[] arr = (A[]) java.lang.reflect.Array.newInstance(annoType, size);
      if (res != null) arr[0] = res;
      return arr;
    }

    // So we have a containing type
    String annoTypeName = annoType.getName();
    String containerTypeName = containerType.getName();
    int directIndex = -1, containerIndex = -1;
    Attribute.Compound direct = null, container = null;
    // Find directly (explicit or implicit) present annotations
    int index = -1;
    for (Attribute.Compound attribute : getAnnotationMirrors()) {
      index++;
      if (attribute.type.tsym.flatName().contentEquals(annoTypeName)) {
        directIndex = index;
        direct = attribute;
      } else if (containerTypeName != null
          && attribute.type.tsym.flatName().contentEquals(containerTypeName)) {
        containerIndex = index;
        container = attribute;
      }
    }

    // Deal with inherited annotations
    if (direct == null && container == null && annoType.isAnnotationPresent(Inherited.class))
      return getInheritedAnnotations(annoType);

    Attribute.Compound[] contained = unpackContained(container);

    // In case of an empty legacy container we might need to look for
    // inherited annos as well
    if (direct == null && contained.length == 0 && annoType.isAnnotationPresent(Inherited.class))
      return getInheritedAnnotations(annoType);

    int size = (direct == null ? 0 : 1) + contained.length;
    @SuppressWarnings("unchecked") // annoType is the Class for A
    A[] arr = (A[]) java.lang.reflect.Array.newInstance(annoType, size);

    // if direct && container, which is first?
    int insert = -1;
    int length = arr.length;
    if (directIndex >= 0 && containerIndex >= 0) {
      if (directIndex < containerIndex) {
        arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
        insert = 1;
      } else {
        arr[arr.length - 1] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
        insert = 0;
        length--;
      }
    } else if (directIndex >= 0) {
      arr[0] = AnnotationProxyMaker.generateAnnotation(direct, annoType);
      return arr;
    } else {
      // Only container
      insert = 0;
    }

    for (int i = 0; i + insert < length; i++)
      arr[insert + i] = AnnotationProxyMaker.generateAnnotation(contained[i], annoType);

    return arr;
  }