@NotNull
  @Override
  public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
    if (!DevKitInspectionUtil.isAllowed(holder.getFile())) return PsiElementVisitor.EMPTY_VISITOR;

    if (!DevKitInspectionUtil.isClassAvailable(holder, PsiElementFactory.class.getName())) {
      return PsiElementVisitor.EMPTY_VISITOR;
    }

    return new JavaElementVisitor() {
      @Override
      public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) {
        String methodName = call.getMethodExpression().getReferenceName();
        if (methodName == null || !methodName.startsWith("create")) return;
        PsiExpression[] args = call.getArgumentList().getExpressions();
        if (args.length == 0) return;
        PsiExpression arg = args[0];
        PsiType argType = arg.getType();
        if (argType == null || !argType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) return;
        PsiMethod method = call.resolveMethod();
        if (method == null) return;
        PsiClass aClass = method.getContainingClass();
        if (aClass == null || !PsiElementFactory.class.getName().equals(aClass.getQualifiedName())) return;
        checkOperand(arg, new HashSet<>());
      }

      private void checkOperand(@Nullable PsiExpression operand, Set<PsiExpression> visited) {
        if (operand == null || !visited.add(operand)) return;
        if (operand instanceof PsiReferenceExpression) {
          PsiElement element = ((PsiReferenceExpression)operand).resolve();
          if (element instanceof PsiLocalVariable &&
              ((PsiLocalVariable)element).getType().equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
            PsiCodeBlock block = PsiTreeUtil.getParentOfType(element, PsiCodeBlock.class);
            if (block != null) {
              PsiElement[] defs = DefUseUtil.getDefs(block, (PsiVariable)element, operand);
              for (PsiElement def : defs) {
                if (def instanceof PsiLocalVariable) {
                  checkOperand(((PsiLocalVariable)def).getInitializer(), visited);
                }
                if (def instanceof PsiReferenceExpression) {
                  PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(def.getParent());
                  if (assignment != null && assignment.getLExpression() == def) {
                    checkOperand(assignment.getRExpression(), visited);
                  }
                }
                if (def instanceof PsiExpression) {
                  checkOperand((PsiExpression)def, visited);
                }
              }
            }
          }
        }
        if (operand instanceof PsiMethodCallExpression call) {
          PsiMethod method = call.resolveMethod();
          if (MethodUtils.isToString(method)) {
            checkOperand(call.getMethodExpression().getQualifierExpression(), visited);
          }
        }
        PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(operand.getType());
        if (InheritanceUtil.isInheritor(aClass, false, PsiElement.class.getName())) {
          holder.registerProblem(operand, DevKitBundle.message("inspections.psi.element.concat.psi.element"),
                                 new AddGetTextFix("getText"));
        }
        if (InheritanceUtil.isInheritor(aClass, false, PsiType.class.getName())) {
          holder.registerProblem(operand, DevKitBundle.message("inspections.psi.element.concat.psi.type"),
                                 new AddGetTextFix("getCanonicalText"));
        }
        if (operand instanceof PsiPolyadicExpression polyadic) {
          if (JavaTokenType.PLUS.equals(polyadic.getOperationTokenType())) {
            for (PsiExpression op : polyadic.getOperands()) {
              checkOperand(op, visited);
            }
          }
        }
      }
    };
  }
@NotNull
  @Override
  public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly)