private static void addKeywordArgumentVariantsForFunction(@NotNull final PyCallExpression callExpr,
                                                            @NotNull final PyFunction function,
                                                            @NotNull final List<String> ret,
                                                            @NotNull final Set<PyCallable> visited,
                                                            @NotNull final TypeEvalContext context) {
    if (visited.contains(function)) {
      return;
    }

    boolean needSelf = function.getContainingClass() != null && function.getModifier() != PyAstFunction.Modifier.STATICMETHOD;
    final KwArgParameterCollector collector = new KwArgParameterCollector(needSelf, ret);

    List<PyCallableParameter> parameters = function.getParameters(context);
    int indexOfPySlashParameter = getIndexOfPySlashParameter(parameters);

    StreamEx
      .of(parameters)
      .skip(indexOfPySlashParameter + 1)
      .map(PyCallableParameter::getParameter)
      .nonNull()
      .forEach(parameter -> parameter.accept(collector));

    if (collector.hasKwArgs()) {
      for (PyKeywordArgumentProvider provider : PyKeywordArgumentProvider.EP_NAME.getExtensionList()) {
        ret.addAll(provider.getKeywordArguments(function, callExpr));
      }
      KwArgFromStatementCallCollector fromStatementCallCollector = new KwArgFromStatementCallCollector(ret, collector.getKwArgs());
      function.getStatementList().acceptChildren(fromStatementCallCollector);

      //if (collector.hasOnlySelfAndKwArgs()) {
      // nothing interesting besides self and **kwargs, let's look at superclass (PY-778)
      if (fromStatementCallCollector.isKwArgsTransit()) {

        final PyFunction superMethod = as(PySuperMethodsSearch.search(function, context).findFirst(), PyFunction.class);
        if (superMethod != null) {
          addKeywordArgumentVariantsForFunction(callExpr, superMethod, ret, visited, context);
        }
      }
    }
  }
private static void addKeywordArgumentVariantsForFunction(@NotNull final PyCallExpression callExpr,
                                                            @NotNull final PyFunction function,
                                                            @NotNull final List<String> ret,
                                                            @NotNull final Set<PyCallable> visited,
                                                            @NotNull final TypeEvalContext context)