@Nullable
  private ProblemDescriptor[] checkMember(
      final PsiDocCommentOwner docCommentOwner,
      final InspectionManager manager,
      final boolean isOnTheFly) {
    final ArrayList<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
    final PsiDocComment docComment = docCommentOwner.getDocComment();
    if (docComment == null) return null;

    final Set<PsiJavaCodeReferenceElement> references = new HashSet<PsiJavaCodeReferenceElement>();
    docComment.accept(getVisitor(references, docCommentOwner, problems, manager, isOnTheFly));
    for (PsiJavaCodeReferenceElement reference : references) {
      final List<PsiClass> classesToImport = new ImportClassFix(reference).getClassesToImport();
      final PsiElement referenceNameElement = reference.getReferenceNameElement();
      problems.add(
          manager.createProblemDescriptor(
              referenceNameElement != null ? referenceNameElement : reference,
              cannotResolveSymbolMessage("<code>" + reference.getText() + "</code>"),
              !isOnTheFly || classesToImport.isEmpty() ? null : new AddImportFix(classesToImport),
              ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
              isOnTheFly));
    }

    return problems.isEmpty() ? null : problems.toArray(new ProblemDescriptor[problems.size()]);
  }
 @Override
 public void ignoreProblem(RefEntity refEntity, CommonProblemDescriptor problem, int idx) {
   if (refEntity == null) return;
   final Set<QuickFix> localQuickFixes = getQuickFixActions().get(refEntity);
   final QuickFix[] fixes = problem.getFixes();
   if (isIgnoreProblem(fixes, localQuickFixes, idx)) {
     getProblemToElements().remove(problem);
     Map<RefEntity, CommonProblemDescriptor[]> problemElements = getProblemElements();
     synchronized (lock) {
       CommonProblemDescriptor[] descriptors = problemElements.get(refEntity);
       if (descriptors != null) {
         ArrayList<CommonProblemDescriptor> newDescriptors =
             new ArrayList<CommonProblemDescriptor>(Arrays.asList(descriptors));
         newDescriptors.remove(problem);
         getQuickFixActions().put(refEntity, null);
         if (!newDescriptors.isEmpty()) {
           problemElements.put(
               refEntity,
               newDescriptors.toArray(new CommonProblemDescriptor[newDescriptors.size()]));
           for (CommonProblemDescriptor descriptor : newDescriptors) {
             collectQuickFixes(descriptor.getFixes(), refEntity);
           }
         } else {
           ignoreProblemElement(refEntity);
         }
       }
     }
   }
 }
  public static void visitRefInDocTag(
      final PsiDocTag tag,
      final JavadocManager manager,
      final PsiElement context,
      final ArrayList<ProblemDescriptor> problems,
      final InspectionManager inspectionManager,
      final boolean onTheFly) {
    final String tagName = tag.getName();
    final PsiDocTagValue value = tag.getValueElement();
    if (value == null) return;
    final JavadocTagInfo info = manager.getTagInfo(tagName);
    if (info != null && !info.isValidInContext(context)) return;
    final String message = info == null || !info.isInline() ? null : info.checkTagValue(value);
    if (message != null) {
      problems.add(createDescriptor(value, message, inspectionManager, onTheFly));
    }

    final PsiReference reference = value.getReference();
    if (reference == null) return;
    final PsiElement element = reference.resolve();
    if (element != null) return;
    final int textOffset = value.getTextOffset();
    if (textOffset == value.getTextRange().getEndOffset()) return;
    final PsiDocTagValue valueElement = tag.getValueElement();
    if (valueElement == null) return;

    final CharSequence paramName =
        value
            .getContainingFile()
            .getViewProvider()
            .getContents()
            .subSequence(textOffset, value.getTextRange().getEndOffset());
    final String params = "<code>" + paramName + "</code>";
    final List<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
    if (onTheFly && "param".equals(tagName)) {
      final PsiDocCommentOwner commentOwner =
          PsiTreeUtil.getParentOfType(tag, PsiDocCommentOwner.class);
      if (commentOwner instanceof PsiMethod) {
        final PsiMethod method = (PsiMethod) commentOwner;
        final PsiParameter[] parameters = method.getParameterList().getParameters();
        final PsiDocTag[] tags = tag.getContainingComment().getTags();
        final Set<String> unboundParams = new HashSet<String>();
        for (PsiParameter parameter : parameters) {
          if (!JavaDocLocalInspection.isFound(tags, parameter)) {
            unboundParams.add(parameter.getName());
          }
        }
        if (!unboundParams.isEmpty()) {
          fixes.add(new RenameReferenceQuickFix(unboundParams));
        }
      }
    }
    fixes.add(new RemoveTagFix(tagName, paramName));

    problems.add(
        inspectionManager.createProblemDescriptor(
            valueElement,
            reference.getRangeInElement(),
            cannotResolveSymbolMessage(params),
            ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
            onTheFly,
            fixes.toArray(new LocalQuickFix[fixes.size()])));
  }
  private void createDescription(
      StandardDataFlowRunner runner, ProblemsHolder holder, DataFlowInstructionVisitor visitor) {
    Pair<Set<Instruction>, Set<Instruction>> constConditions =
        runner.getConstConditionalExpressions();
    Set<Instruction> trueSet = constConditions.getFirst();
    Set<Instruction> falseSet = constConditions.getSecond();

    ArrayList<Instruction> allProblems = new ArrayList<Instruction>();
    allProblems.addAll(trueSet);
    allProblems.addAll(falseSet);
    allProblems.addAll(runner.getCCEInstructions());
    allProblems.addAll(StandardDataFlowRunner.getRedundantInstanceofs(runner, visitor));

    HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>();
    for (PsiElement element : visitor.getProblems(NullabilityProblem.callNPE)) {
      if (reportedAnchors.add(element)) {
        reportCallMayProduceNpe(holder, (PsiMethodCallExpression) element, holder.isOnTheFly());
      }
    }
    for (PsiElement element : visitor.getProblems(NullabilityProblem.fieldAccessNPE)) {
      if (reportedAnchors.add(element)) {
        PsiElement parent = element.getParent();
        PsiElement fieldAccess =
            parent instanceof PsiArrayAccessExpression || parent instanceof PsiReferenceExpression
                ? parent
                : element;
        reportFieldAccessMayProduceNpe(holder, element, (PsiExpression) fieldAccess);
      }
    }

    for (Instruction instruction : allProblems) {
      if (instruction instanceof TypeCastInstruction
          && reportedAnchors.add(
              ((TypeCastInstruction) instruction).getCastExpression().getCastType())) {
        reportCastMayFail(holder, (TypeCastInstruction) instruction);
      } else if (instruction instanceof BranchingInstruction) {
        handleBranchingInstruction(
            holder,
            visitor,
            trueSet,
            falseSet,
            reportedAnchors,
            (BranchingInstruction) instruction);
      }
    }

    reportNullableArguments(visitor, holder, reportedAnchors);
    reportNullableAssignments(visitor, holder, reportedAnchors);
    reportUnboxedNullables(visitor, holder, reportedAnchors);
    if (!runner.isInNullableMethod()
        && runner.isInMethod()
        && (runner.isInNotNullMethod() || SUGGEST_NULLABLE_ANNOTATIONS)) {
      reportNullableReturns(runner, visitor, holder, reportedAnchors);
    }
    if (SUGGEST_NULLABLE_ANNOTATIONS) {
      reportNullableArgumentsPassedToNonAnnotated(visitor, holder, reportedAnchors);
    }

    if (REPORT_CONSTANT_REFERENCE_VALUES) {
      reportConstantReferenceValues(holder, visitor, reportedAnchors);
    }
  }