@Override
  public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
    LanguageLevel languageLevel = PsiUtil.getLanguageLevel(holder.getFile());
    return new JavaElementVisitor() {
      @Override
      public void visitIdentifier(@NotNull PsiIdentifier identifier) {
        String message = getIdentifierWarning(identifier);
        if (message != null) {
          holder.registerProblem(identifier, message, new RenameFix());
        }
      }

      private @Nullable @InspectionMessage String getIdentifierWarning(PsiIdentifier identifier) {
        String name = identifier.getText();
        PsiElement parent = identifier.getParent();
        JavaFeature feature = PsiUtil.softKeywordFeature(name);
        if (feature != null && 
            feature != JavaFeature.MODULES && !name.equals(PsiKeyword.WHEN) && // Keywords from module-info and 'when' still can be used as class names
            !feature.isSufficient(languageLevel) && parent instanceof PsiClass) {
          return JavaErrorBundle.message("restricted.identifier.warn", name,
                                         feature.getMinimumLevel().feature());
        }
        switch (name) {
          case PsiKeyword.ASSERT -> {
            if (!JavaFeature.ASSERTIONS.isSufficient(languageLevel) &&
                (parent instanceof PsiClass || parent instanceof PsiMethod || parent instanceof PsiVariable)) {
              return JavaErrorBundle.message("assert.identifier.warn");
            }
          }
          case PsiKeyword.ENUM -> {
            if (!JavaFeature.ENUMS.isSufficient(languageLevel) &&
                (parent instanceof PsiClass || parent instanceof PsiMethod || parent instanceof PsiVariable)) {
              return JavaErrorBundle.message("enum.identifier.warn");
            }
          }
          case "_" -> {
            if (languageLevel.isLessThan(LanguageLevel.JDK_1_9)) {
              return JavaErrorBundle.message("underscore.identifier.warn");
            }
          }
        }
        return null;
      }

      @Override
      public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
        PsiReferenceExpression ref = expression.getMethodExpression();
        PsiElement nameElement = ref.getReferenceNameElement();
        if (nameElement != null && PsiKeyword.YIELD.equals(nameElement.getText()) && ref.getQualifierExpression() == null &&
            !JavaFeature.SWITCH_EXPRESSION.isSufficient(languageLevel)) {
          PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(expression.getMethodExpression());
          holder.registerProblem(nameElement, JavaErrorBundle.message("yield.unqualified.method.warn"),
                                   qualifier == null ? null : new QualifyCallFix(), new RenameFix());
        }
      }

      @Override
      public void visitKeyword(@NotNull PsiKeyword keyword) {
        super.visitKeyword(keyword);
        if (languageLevel.isAtLeast(LanguageLevel.JDK_1_9) && !languageLevel.isAtLeast(LanguageLevel.JDK_10)) {
          @PsiModifier.ModifierConstant String modifier = keyword.getText();
          if (PsiKeyword.STATIC.equals(modifier) || PsiKeyword.TRANSITIVE.equals(modifier)) {
            PsiElement parent = keyword.getParent();
            if (parent instanceof PsiModifierList) {
              PsiElement grand = parent.getParent();
              if (grand instanceof PsiRequiresStatement && PsiJavaModule.JAVA_BASE.equals(((PsiRequiresStatement)grand).getModuleName())) {
                String message = JavaErrorBundle.message("module.unwanted.modifier.warn");
                LocalQuickFix fix = QuickFixFactory.getInstance().createModifierListFix((PsiModifierList)parent, modifier, false, false);
                holder.registerProblem(keyword, message, fix);
              }
            }
          }
        }
      }

      @Override
      public void visitJavaToken(@NotNull PsiJavaToken token) {
        super.visitJavaToken(token);
        if (languageLevel.isLessThan(LanguageLevel.JDK_21) &&
            token.getTokenType() == JavaTokenType.SEMICOLON &&
            PsiUtil.isFollowedByImport(token)) {
          String message = JavaErrorBundle.message("redundant.semicolon.warn");
          holder.registerProblem(token, message, new UnnecessarySemicolonInspection.UnnecessarySemicolonFix());
        }
      }
    };
  }
@Override
  public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly)