@NotNull
  public static ArgumentMappingResults analyzeArguments(@NotNull List<PyExpression> arguments,
                                                         @NotNull List<PyCallableParameter> parameters,
                                                         @NotNull TypeEvalContext context) {
    boolean positionalOnlyMode = ContainerUtil.exists(parameters, p -> p.getParameter() instanceof PySlashParameter);
    boolean seenSingleStar = false;
    boolean mappedVariadicArgumentsToParameters = false;
    final Map<PyExpression, PyCallableParameter> mappedParameters = new LinkedHashMap<>();
    final List<PyCallableParameter> unmappedParameters = new ArrayList<>();
    final List<PyCallableParameter> unmappedContainerParameters = new ArrayList<>();
    final List<PyExpression> unmappedArguments = new ArrayList<>();
    final List<PyCallableParameter> parametersMappedToVariadicKeywordArguments = new ArrayList<>();
    final List<PyCallableParameter> parametersMappedToVariadicPositionalArguments = new ArrayList<>();
    final Map<PyExpression, PyCallableParameter> tupleMappedParameters = new LinkedHashMap<>();

    final PositionalArgumentsAnalysisResults positionalResults = filterPositionalAndVariadicArguments(arguments);
    final List<PyKeywordArgument> keywordArguments = filterKeywordArguments(arguments);
    final List<PyExpression> variadicPositionalArguments = positionalResults.variadicPositionalArguments;
    final Set<PyExpression> positionalComponentsOfVariadicArguments =
      new LinkedHashSet<>(positionalResults.componentsOfVariadicPositionalArguments);
    final List<PyExpression> variadicKeywordArguments = filterVariadicKeywordArguments(arguments);

    final List<PyExpression> allPositionalArguments = positionalResults.allPositionalArguments;

    for (PyCallableParameter parameter : parameters) {
      final PyParameter psi = parameter.getParameter();

      if (psi instanceof PyNamedParameter || psi == null) {
        final String parameterName = parameter.getName();
        if (parameter.isPositionalContainer()) {
          for (PyExpression argument : allPositionalArguments) {
            if (argument != null) {
              mappedParameters.put(argument, parameter);
            }
          }
          if (variadicPositionalArguments.size() == 1) {
            mappedParameters.put(variadicPositionalArguments.get(0), parameter);
          }
          if (variadicPositionalArguments.size() != 1 && allPositionalArguments.size() == 0) {
            unmappedContainerParameters.add(parameter);
          }
          allPositionalArguments.clear();
          variadicPositionalArguments.clear();
        }
        else if (parameter.isKeywordContainer()) {
          for (PyKeywordArgument argument : keywordArguments) {
            mappedParameters.put(argument, parameter);
          }
          for (PyExpression variadicKeywordArg : variadicKeywordArguments) {
            mappedParameters.put(variadicKeywordArg, parameter);
          }
          keywordArguments.clear();
          variadicKeywordArguments.clear();
        }
        else if (seenSingleStar) {
          final PyExpression keywordArgument = removeKeywordArgument(keywordArguments, parameterName);
          if (keywordArgument != null) {
            mappedParameters.put(keywordArgument, parameter);
          }
          else if (variadicKeywordArguments.isEmpty()) {
            if (!parameter.hasDefaultValue()) {
              unmappedParameters.add(parameter);
            }
          }
          else {
            parametersMappedToVariadicKeywordArguments.add(parameter);
            mappedVariadicArgumentsToParameters = true;
          }
        }
        else if (isParamSpecOrConcatenate(parameter, context)) {
          for (var argument: arguments) {
            mappedParameters.put(argument, parameter);
          }
          allPositionalArguments.clear();
          keywordArguments.clear();
          variadicPositionalArguments.clear();
          variadicKeywordArguments.clear();
        }
        else {
          if (positionalOnlyMode) {
            final PyExpression positionalArgument = next(allPositionalArguments);

            if (positionalArgument != null) {
              mappedParameters.put(positionalArgument, parameter);
            }
            else if (!parameter.hasDefaultValue()) {
              unmappedParameters.add(parameter);
            }
          }
          else if (allPositionalArguments.isEmpty()) {
            final PyKeywordArgument keywordArgument = removeKeywordArgument(keywordArguments, parameterName);
            if (keywordArgument != null) {
              mappedParameters.put(keywordArgument, parameter);
            }
            else if (variadicPositionalArguments.isEmpty() && variadicKeywordArguments.isEmpty() && !parameter.hasDefaultValue()) {
              unmappedParameters.add(parameter);
            }
            else {
              if (!variadicPositionalArguments.isEmpty()) {
                parametersMappedToVariadicPositionalArguments.add(parameter);
              }
              if (!variadicKeywordArguments.isEmpty()) {
                parametersMappedToVariadicKeywordArguments.add(parameter);
              }
              mappedVariadicArgumentsToParameters = true;
            }
          }
          else {
            final PyExpression positionalArgument = next(allPositionalArguments);
            if (positionalArgument != null) {
              mappedParameters.put(positionalArgument, parameter);
              if (positionalComponentsOfVariadicArguments.contains(positionalArgument)) {
                parametersMappedToVariadicPositionalArguments.add(parameter);
              }
            }
            else if (!parameter.hasDefaultValue()) {
              unmappedParameters.add(parameter);
            }
          }
        }
      }
      else if (psi instanceof PyTupleParameter) {
        final PyExpression positionalArgument = next(allPositionalArguments);
        if (positionalArgument != null) {
          tupleMappedParameters.put(positionalArgument, parameter);
          final TupleMappingResults tupleMappingResults = mapComponentsOfTupleParameter(positionalArgument, (PyTupleParameter)psi);
          mappedParameters.putAll(tupleMappingResults.getParameters());
          unmappedParameters.addAll(tupleMappingResults.getUnmappedParameters());
          unmappedArguments.addAll(tupleMappingResults.getUnmappedArguments());
        }
        else if (variadicPositionalArguments.isEmpty()) {
          if (!parameter.hasDefaultValue()) {
            unmappedParameters.add(parameter);
          }
        }
        else {
          mappedVariadicArgumentsToParameters = true;
        }
      }
      else if (psi instanceof PySlashParameter) {
        positionalOnlyMode = false;
      }
      else if (psi instanceof PySingleStarParameter) {
        seenSingleStar = true;
      }
      else if (!parameter.hasDefaultValue()) {
        unmappedParameters.add(parameter);
      }
    }

    if (mappedVariadicArgumentsToParameters) {
      variadicPositionalArguments.clear();
      variadicKeywordArguments.clear();
    }

    unmappedArguments.addAll(allPositionalArguments);
    unmappedArguments.addAll(keywordArguments);
    unmappedArguments.addAll(variadicPositionalArguments);
    unmappedArguments.addAll(variadicKeywordArguments);

    return new ArgumentMappingResults(mappedParameters, unmappedParameters, unmappedContainerParameters, unmappedArguments,
                                      parametersMappedToVariadicPositionalArguments, parametersMappedToVariadicKeywordArguments,
                                      tupleMappedParameters);
  }
@NotNull
  public static ArgumentMappingResults analyzeArguments(@NotNull List<PyExpression> arguments,
                                                         @NotNull List<PyCallableParameter> parameters,
                                                         @NotNull TypeEvalContext context)