private static boolean matchTypeParameters(@NotNull List<PyType> expectedTypeParameters,
                                             @NotNull List<PyType> actualTypeParameters,
                                             @NotNull MatchContext context) {
    PyTypeParameterMapping mapping =
      PyTypeParameterMapping.mapByShape(expectedTypeParameters, actualTypeParameters);
    if (mapping == null) {
      return false;
    }
    for (Couple<PyType> pair : mapping.getMappedTypes()) {
      Optional<Boolean> matched = context.reversedSubstitutions
                                  ? match(pair.getSecond(), pair.getFirst(), context)
                                  : match(pair.getFirst(), pair.getSecond(), context);
      if (!matched.orElse(true)) {
        return false;
      }
    }
    return true;
  }
private static boolean matchTypeParameters(@NotNull List<PyType> expectedTypeParameters,
                                             @NotNull List<PyType> actualTypeParameters,
                                             @NotNull MatchContext context)