@SuppressWarnings("rawtypes") // DOM AST API returns raw collections
  public SourcePosition getPosition() {
    final MirrorKind kind = _parent.kind();
    ASTNode astNode = null;
    switch (kind) {
      case ANNOTATION_MIRROR:
        final AnnotationMirrorImpl anno = (AnnotationMirrorImpl) _parent;
        astNode = anno.getASTNodeForElement(_name);
        break;
      case ANNOTATION_ELEMENT:
        final AnnotationElementDeclarationImpl element = (AnnotationElementDeclarationImpl) _parent;
        astNode = element.getAstNodeForDefault();
        break;
      default:
        throw new IllegalStateException(); // should never reach this point.
    }
    // did not come from source.
    if (astNode == null) return null;
    if (_index >= 0 && astNode.getNodeType() == ASTNode.ARRAY_INITIALIZER) {
      final ArrayInitializer arrayInit = (ArrayInitializer) astNode;
      final List exprs = arrayInit.expressions();
      if (exprs != null && _index < exprs.size()) astNode = (ASTNode) exprs.get(_index);
    }
    if (astNode == null) return null;

    final CompilationUnit unit = getCompilationUnit();
    if (unit == null) return null;
    final int offset = astNode.getStartPosition();
    return new SourcePositionImpl(
        astNode.getStartPosition(),
        astNode.getLength(),
        unit.getLineNumber(offset),
        unit.getColumnNumber(offset),
        this);
  }
 public IFile getResource() {
   final MirrorKind kind = _parent.kind();
   switch (kind) {
     case ANNOTATION_MIRROR:
       return ((AnnotationMirrorImpl) _parent).getResource();
     case ANNOTATION_ELEMENT:
       if (((EclipseDeclarationImpl) _parent).isBindingBased())
         return ((AnnotationElementDeclarationImpl) _parent).getResource();
       else return ((ASTBasedAnnotationElementDeclarationImpl) _parent).getResource();
     default:
       throw new IllegalStateException(); // should never reach this point.
   }
 }