private static List<Pair<String, PsiType>> suggestCollectors(Collection<? extends ExpectedTypeInfo> expectedTypes, PsiExpression qualifier) {
    PsiType component = PsiUtil.substituteTypeParameter(qualifier.getType(), JAVA_UTIL_STREAM_STREAM, 0, true);
    if (component == null) return Collections.emptyList();

    JavaPsiFacade facade = JavaPsiFacade.getInstance(qualifier.getProject());
    PsiElementFactory factory = facade.getElementFactory();
    GlobalSearchScope scope = qualifier.getResolveScope();

    boolean joiningApplicable = InheritanceUtil.isInheritor(component, CharSequence.class.getName());

    PsiClass list = facade.findClass(JAVA_UTIL_LIST, scope);
    PsiClass set = facade.findClass(JAVA_UTIL_SET, scope);
    PsiClass collection = facade.findClass(JAVA_UTIL_COLLECTION, scope);
    PsiClass string = facade.findClass(JAVA_LANG_STRING, scope);
    if (list == null || set == null || collection == null || string == null) return Collections.emptyList();

    PsiType listType = null;
    PsiType setType = null;
    for (ExpectedTypeInfo info : expectedTypes) {
      PsiType type = info.getDefaultType();
      PsiClass expectedClass = PsiUtil.resolveClassInClassTypeOnly(type);
      PsiType expectedComponent = PsiUtil.extractIterableTypeParameter(type, true);
      if (expectedClass == null || expectedComponent == null || !TypeConversionUtil.isAssignable(expectedComponent, component)) continue;

      if (InheritanceUtil.isInheritorOrSelf(list, expectedClass, true)) {
        listType = type;
      }
      if (InheritanceUtil.isInheritorOrSelf(set, expectedClass, true)) {
        setType = type;
      }
    }

    if (listType == null) {
      listType = factory.createType(list, component);
    }

    if (setType == null) {
      setType = factory.createType(set, component);
    }

    List<Pair<String, PsiType>> result = new ArrayList<>();
    if (PsiUtil.getLanguageLevel(qualifier).isLessThan(LanguageLevel.JDK_16)) {
      result.add(Pair.create("toList", listType));
    }
    result.add(Pair.create("toUnmodifiableList", listType));
    result.add(Pair.create("toSet", setType));
    result.add(Pair.create("toUnmodifiableSet", setType));
    result.add(Pair.create("toCollection", factory.createType(collection, component)));
    if (joiningApplicable) {
      result.add(Pair.create("joining", factory.createType(string)));
    }
    return result;
  }
private static List<Pair<String, PsiType>> suggestCollectors(Collection<? extends ExpectedTypeInfo> expectedTypes, PsiExpression qualifier)