@Override
    public void visitCallExpression(@NotNull PsiCallExpression expression) {
      PsiExpressionList list = expression.getArgumentList();
      if (list == null) {
        return;
      }
      FormatDecode.FormatArgument formatArgument = FormatDecode.FormatArgument.extract(expression, methodNames, classNames, true);
      if (formatArgument == null) {
        return;
      }

      int formatArgumentIndex = formatArgument.getIndex();

      PsiExpression[] arguments = list.getExpressions();

      int argumentCount = arguments.length - formatArgumentIndex;

      String value = formatArgument.calculateValue();
      final FormatDecode.Validator[] validators;
      boolean isPrefix = false;
      if (value != null) {
        try {
          validators = FormatDecode.decode(value, argumentCount);
        }
        catch (FormatDecode.IllegalFormatException e) {
          registerError(formatArgument.getExpression(), e);
          return;
        }
      }
      else {
        String prefixValue = formatArgument.calculatePrefixValue();
        isPrefix = true;
        if (prefixValue == null) {
          return;
        }
        try {
          validators = FormatDecode.decodePrefix(prefixValue, argumentCount);
        }
        catch (FormatDecode.IllegalFormatException e) {
          registerError(formatArgument.getExpression(), e);
          return;
        }
      }

      if (argumentCount == 1) {
        final PsiExpression argument = resolveIfPossible(arguments[formatArgumentIndex]);
        final PsiType argumentType = argument.getType();
        if (argumentType instanceof PsiArrayType) {
          final PsiArrayInitializerExpression arrayInitializer;
          if (argument instanceof PsiNewExpression newExpression) {
            arrayInitializer = newExpression.getArrayInitializer();
          }
          else if (argument instanceof PsiArrayInitializerExpression) {
            arrayInitializer = (PsiArrayInitializerExpression)argument;
          }
          else {
            return;
          }
          if (arrayInitializer == null) {
            return;
          }
          arguments = arrayInitializer.getInitializers();
          argumentCount = arguments.length;
          formatArgumentIndex = 0;
        }
      }
      if ((!isPrefix && validators.length != argumentCount) ||
          (isPrefix && validators.length > argumentCount)) {
        if (expression instanceof PsiMethodCallExpression) {
          registerMethodCallError((PsiMethodCallExpression)expression, validators, Integer.valueOf(argumentCount), isPrefix);
        }
        else if (expression instanceof PsiNewExpression) {
          registerNewExpressionError((PsiNewExpression)expression, validators, Integer.valueOf(argumentCount), isPrefix);
        }
        return;
      }
      for (int i = 0; i < validators.length; i++) {
        final FormatDecode.Validator validator = validators[i];
        final PsiExpression argument = arguments[i + formatArgumentIndex];
        final PsiType argumentType = argument.getType();
        if (argumentType == null) {
          continue;
        }
        if (validator != null && !validator.valid(argumentType)) {
          PsiType preciseType = TypeConstraint.fromDfType(CommonDataflow.getDfType(argument)).getPsiType(expression.getProject());
          if (preciseType == null || !validator.valid(preciseType)) {
            registerError(argument, validators, Integer.valueOf(argumentCount), argumentType, validator);
          }
        }
      }
    }
@Override
    public void visitCallExpression(@NotNull PsiCallExpression expression)