@NotNull
  @Override
  public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
    return new JavaElementVisitor() {
      @Override
      public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
        handle(expression);
      }
      
      @Override
      public void visitExpression(@NotNull PsiExpression expression) {
        handle(expression);
      }
      
      private void handle(@NotNull PsiExpression expression) {
        if (expression instanceof PsiLiteralExpression) return;
        // inspection disabled for long expressions because of performance issues on
        // relatively common large string expressions.
        Object value = computeConstant(expression);
        if (value == null) return;
        if (value instanceof PsiField && !(value instanceof PsiEnumConstant)) return;
        if (value instanceof PsiElement e && expression instanceof PsiReferenceExpression ref && ref.isReferenceTo(e)) return;
        String valueText = getValueText(value);
        if (valueText == null || expression.textMatches(valueText)) return;
        String message = valueText.length() > MAX_RESULT_LENGTH_TO_DISPLAY ?
                         InspectionGadgetsBundle.message("inspection.constant.expression.display.name") :
                         InspectionGadgetsBundle.message("inspection.constant.expression.message", valueText);
        if (skipIfContainsReferenceExpression && hasReferences(expression)) {
          if (isOnTheFly) {
            holder.registerProblem(expression, message, ProblemHighlightType.INFORMATION,
                                   new ComputeConstantValueFix(expression, valueText));
          }
        }
        else {
          holder.registerProblem(expression, message,
                                 new ComputeConstantValueFix(expression, valueText));
        }
      }

      @Nullable
      private Object computeConstant(PsiExpression expression) {
        if (expression.getTextLength() > MAX_EXPRESSION_LENGTH) return null;
        if (expression.getType() == null) return null;
        Object value = computeValue(expression);
        if (value == null) return null;
        final PsiExpression parent = getParentExpression(expression);
        if (parent != null && computeValue(parent) != null) return null;
        return value;
      }

      private Object computeValue(PsiExpression expression) {
        if (expression instanceof PsiClassObjectAccessExpression) return null;
        try {
          Object value = ExpressionUtils.computeConstantExpression(expression, true);
          if (value != null && !(value instanceof Enum<?>)) {
            return value;
          }
        }
        catch (ConstantEvaluationOverflowException ignore) {
          return null;
        }
        if (reportOnlyCompileTimeConstants) return null;
        if (SideEffectChecker.mayHaveSideEffects(expression)) return null;
        return CommonDataflow.computeValue(expression);
      }

      @Nullable
      private static PsiExpression getParentExpression(PsiExpression expression) {
        PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
        if (parent instanceof PsiExpressionList || parent instanceof PsiTemplate) {
          parent = parent.getParent();
        }
        return tryCast(parent, PsiExpression.class);
      }

      private static boolean hasReferences(@NotNull PsiExpression expression) {
        return expression instanceof PsiReferenceExpression || 
               PsiTreeUtil.getChildOfType(expression, PsiReferenceExpression.class) != null;
      }
    };
  }
@NotNull
  @Override
  public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly)