@Override
  public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session) {
    return new JavaElementVisitor() {
      @Override
      public void visitTypeElement(@NotNull PsiTypeElement typeElement) {
        VarianceCandidate candidate = VarianceCandidate.findVarianceCandidate(typeElement);
        if (candidate == null) return;
        PsiTypeParameterListOwner owner = candidate.typeParameter.getOwner();
        if (owner instanceof PsiClass && !REPORT_INVARIANT_CLASSES && VarianceUtil.getClassVariance((PsiClass)owner, candidate.typeParameter) == Variance.INVARIANT) {
          return; // Nikolay despises List<? extends T>
        }
        PsiClass containingClass = candidate.method.getContainingClass();
        if (!REPORT_PRIVATE_METHODS && (candidate.method.hasModifierProperty(PsiModifier.PRIVATE)
                                        // methods of private class considered private for the purpose of this inspection
                                        || containingClass != null && containingClass.hasModifierProperty(PsiModifier.PRIVATE))) {
          return; // somebody hates his precious private methods highlighted
        }
        if (!REPORT_INSTANCE_METHODS &&
            !candidate.method.hasModifierProperty(PsiModifier.STATIC) &&
            !candidate.method.isConstructor()) {
          return; // somebody doesn't want to report instance methods highlighted because they can be already overridden
        }
        Project project = holder.getProject();
        boolean canBeSuper = canChangeTo(project, candidate, false);
        boolean canBeExtends = canChangeTo(project, candidate, true);
        if (canBeExtends == canBeSuper || VarianceUtil.areBoundsSaturated(candidate, canBeExtends)) return;

        boolean wildCardIsUseless = VarianceUtil.wildCardIsUseless(candidate, canBeExtends);
        ProblemHighlightType type = wildCardIsUseless ? ProblemHighlightType.WEAK_WARNING : ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
        String msg = canBeExtends
                      ? InspectionGadgetsBundle.message("bounded.wildcard.covariant.descriptor")
                      : InspectionGadgetsBundle.message("bounded.wildcard.contravariant.descriptor");
        // show verbose message in debug mode only
        if (!wildCardIsUseless || LOG.isDebugEnabled()) {
          @NonNls String verboseDebugMessage = " but decided against it";
          holder.registerProblem(typeElement, msg + (wildCardIsUseless ? verboseDebugMessage : ""), type, new ReplaceWithQuestionTFix(isOverriddenOrOverrides(candidate.method), canBeExtends));
        }
      }
    };
  }
@Override
  public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session)