@Override
  public List<ErrorDescription> run(CompilationInfo info, TreePath treePath) {
    Tree t = treePath.getLeaf();
    JTextComponent editor = EditorRegistry.lastFocusedComponent();
    Document doc = editor.getDocument();

    SourcePositions sp = info.getTrees().getSourcePositions();
    int start = (int) sp.getStartPosition(info.getCompilationUnit(), t);
    int end = (int) sp.getEndPosition(info.getCompilationUnit(), t);
    int endLine = info.getText().indexOf("\n", start);
    String line = info.getText().substring(start, endLine).trim();

    if (!Suppression.isSuppressed(line)) {
      return Collections.<ErrorDescription>singletonList(
          ErrorDescriptionFactory.createErrorDescription(
              Severity.HINT,
              ERROR_DESCRIPTION,
              createFixes(doc, start, endLine),
              info.getFileObject(),
              start,
              end));
    } else {
      return null;
    }
  }
      @Override
      public void run(final CompilationInfo parameter) {
        TypeElement clazz = parameter.getElements().getTypeElement(annotation.getClassName());

        if (clazz == null) {
          // XXX: log
          return;
        }

        Element resolved = null;

        if (annotation instanceof FieldAnnotation) {
          FieldAnnotation fa = (FieldAnnotation) annotation;

          for (VariableElement var : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
            if (var.getSimpleName().contentEquals(fa.getFieldName())) {
              resolved = var;
              break;
            }
          }
        } else if (annotation instanceof MethodAnnotation) {
          MethodAnnotation ma = (MethodAnnotation) annotation;

          for (ExecutableElement method : ElementFilter.methodsIn(clazz.getEnclosedElements())) {
            if (method.getSimpleName().contentEquals(ma.getMethodName())) {
              if (ma.getMethodSignature()
                  .equals(SourceUtils.getJVMSignature(ElementHandle.create(method))[2])) {
                resolved = method;
                break;
              }
            }
          }
        } else if (annotation instanceof ClassAnnotation) {
          resolved = clazz;
        }

        if (resolved == null) {
          // XXX: log
          return;
        }

        final Element resolvedFin = resolved;

        new CancellableTreePathScanner<Void, Void>() {
          @Override
          public Void visitVariable(VariableTree node, Void p) {
            if (resolvedFin.equals(parameter.getTrees().getElement(getCurrentPath()))) {
              int[] span = parameter.getTreeUtilities().findNameSpan(node);

              if (span != null) {
                result[0] = span[0];
                result[1] = span[1];
              }
            }

            return super.visitVariable(node, p);
          }

          @Override
          public Void visitMethod(MethodTree node, Void p) {
            if (resolvedFin.equals(parameter.getTrees().getElement(getCurrentPath()))) {
              int[] span = parameter.getTreeUtilities().findNameSpan(node);

              if (span != null) {
                result[0] = span[0];
                result[1] = span[1];
              }
            }

            return super.visitMethod(node, p);
          }

          @Override
          public Void visitClass(ClassTree node, Void p) {
            if (resolvedFin.equals(parameter.getTrees().getElement(getCurrentPath()))) {
              int[] span = parameter.getTreeUtilities().findNameSpan(node);

              if (span != null) {
                result[0] = span[0];
                result[1] = span[1];
              }
            }

            return super.visitClass(node, p);
          }
        }.scan(parameter.getCompilationUnit(), null);
      }
  private static List<? extends TypeMirror> computeMethod(
      Set<ElementKind> types,
      CompilationInfo info,
      TreePath parent,
      TypeMirror[] typeParameterBound,
      Tree error,
      int offset) {
    // class or field:
    // check the error is in the body:
    // #92419: check for abstract method/method without body:
    MethodTree mt = (MethodTree) parent.getLeaf();

    if (mt.getReturnType() == error) {
      types.add(ElementKind.CLASS);
      types.add(ElementKind.INTERFACE);
      types.add(ElementKind.ENUM);
    }

    List<? extends ExpressionTree> throwList = mt.getThrows();
    if (throwList != null && !throwList.isEmpty()) {
      for (ExpressionTree t : throwList) {
        if (t == error) {
          types.add(ElementKind.CLASS);
          typeParameterBound[0] = info.getElements().getTypeElement("java.lang.Exception").asType();
          break;
        }
      }
    }

    if (mt.getBody() == null) {
      return null;
    }

    try {
      Document doc = info.getDocument();

      if (doc != null) { // XXX
        int bodyStart =
            Utilities.findBodyStart(
                parent.getLeaf(),
                info.getCompilationUnit(),
                info.getTrees().getSourcePositions(),
                doc);
        int bodyEnd =
            (int)
                info.getTrees()
                    .getSourcePositions()
                    .getEndPosition(info.getCompilationUnit(), parent.getLeaf());

        types.add(ElementKind.PARAMETER);
        types.add(ElementKind.LOCAL_VARIABLE);
        types.add(ElementKind.FIELD);

        if (bodyStart <= offset && offset <= bodyEnd)
          return Collections.singletonList(
              info.getElements().getTypeElement("java.lang.Object").asType());
      }
    } catch (IOException ex) {
      Logger.getLogger("global").log(Level.INFO, ex.getMessage(), ex);
    }

    return null;
  }