public static void getMissingJavadocTagProposals(
      IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
    ASTNode node = problem.getCoveringNode(context.getASTRoot());
    if (node == null) {
      return;
    }
    node = ASTNodes.getNormalizedNode(node);

    BodyDeclaration bodyDeclaration = ASTResolving.findParentBodyDeclaration(node);
    if (bodyDeclaration == null) {
      return;
    }
    Javadoc javadoc = bodyDeclaration.getJavadoc();
    if (javadoc == null) {
      return;
    }

    String label;
    StructuralPropertyDescriptor location = node.getLocationInParent();
    if (location == SingleVariableDeclaration.NAME_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_paramtag_description;
      if (node.getParent().getLocationInParent() != MethodDeclaration.PARAMETERS_PROPERTY) {
        return; // paranoia checks
      }
    } else if (location == TypeParameter.NAME_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_paramtag_description;
      StructuralPropertyDescriptor parentLocation = node.getParent().getLocationInParent();
      if (parentLocation != MethodDeclaration.TYPE_PARAMETERS_PROPERTY
          && parentLocation != TypeDeclaration.TYPE_PARAMETERS_PROPERTY) {
        return; // paranoia checks
      }
    } else if (location == MethodDeclaration.RETURN_TYPE2_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_returntag_description;
    } else if (location == MethodDeclaration.THROWN_EXCEPTION_TYPES_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_throwstag_description;
    } else {
      return;
    }
    ASTRewriteCorrectionProposal proposal =
        new AddMissingJavadocTagProposal(
            label,
            context.getCompilationUnit(),
            bodyDeclaration,
            node,
            IProposalRelevance.ADD_MISSING_TAG);
    proposals.add(proposal);

    String label2 = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_allmissing_description;
    ASTRewriteCorrectionProposal addAllMissing =
        new AddAllMissingJavadocTagsProposal(
            label2,
            context.getCompilationUnit(),
            bodyDeclaration,
            IProposalRelevance.ADD_ALL_MISSING_TAGS);
    proposals.add(addAllMissing);
  }
  public static void getUnusedAndUndocumentedParameterOrExceptionProposals(
      IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
    ICompilationUnit cu = context.getCompilationUnit();
    IJavaProject project = cu.getJavaProject();

    if (!JavaCore.ENABLED.equals(project.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, true))) {
      return;
    }

    int problemId = problem.getProblemId();
    boolean isUnusedTypeParam = problemId == IProblem.UnusedTypeParameter;
    boolean isUnusedParam = problemId == IProblem.ArgumentIsNeverUsed || isUnusedTypeParam;
    String key =
        isUnusedParam
            ? JavaCore.COMPILER_PB_UNUSED_PARAMETER_INCLUDE_DOC_COMMENT_REFERENCE
            : JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE;

    if (!JavaCore.ENABLED.equals(project.getOption(key, true))) {
      return;
    }

    ASTNode node = problem.getCoveringNode(context.getASTRoot());
    if (node == null) {
      return;
    }

    BodyDeclaration bodyDecl = ASTResolving.findParentBodyDeclaration(node);
    if (bodyDecl == null || ASTResolving.getParentMethodOrTypeBinding(bodyDecl) == null) {
      return;
    }

    String label;
    if (isUnusedTypeParam) {
      label = CorrectionMessages.JavadocTagsSubProcessor_document_type_parameter_description;
    } else if (isUnusedParam) {
      label = CorrectionMessages.JavadocTagsSubProcessor_document_parameter_description;
    } else {
      node = ASTNodes.getNormalizedNode(node);
      label = CorrectionMessages.JavadocTagsSubProcessor_document_exception_description;
    }
    ASTRewriteCorrectionProposal proposal =
        new AddMissingJavadocTagProposal(
            label,
            context.getCompilationUnit(),
            bodyDecl,
            node,
            IProposalRelevance.DOCUMENT_UNUSED_ITEM);
    proposals.add(proposal);
  }