private static boolean shouldCast(@NotNull LookupElement item,
                                    @NotNull PsiTypeLookupItem castTypeItem,
                                    @Nullable PsiType plainQualifier,
                                    @NotNull JavaCompletionProcessor processor,
                                    @NotNull Set<? extends PsiType> expectedTypes) {
    PsiType castType = castTypeItem.getType();
    if (plainQualifier != null) {
      Object o = item.getObject();
      if (o instanceof PsiMethod) {
        if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) {
          PsiMethod method = (PsiMethod)o;
          PsiClassType.ClassResolveResult plainResult = ((PsiClassType)plainQualifier).resolveGenerics();
          PsiClass plainClass = plainResult.getElement();
          HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
          PsiMethod plainMethod = plainClass == null ? null :
                                  StreamEx.ofTree(signature, s -> StreamEx.of(s.getSuperSignatures()))
                                    .map(sig -> MethodSignatureUtil.findMethodBySignature(plainClass, sig, true))
                                    .filter(Objects::nonNull)
                                    .findFirst().orElse(null);
          if (plainMethod != null) {
            PsiClassType.ClassResolveResult castResult = ((PsiClassType)castType).resolveGenerics();
            PsiClass castClass = castResult.getElement();

            if (castClass == null || !castClass.isInheritor(plainClass, true)) {
              return false;
            }

            if (!processor.isAccessible(plainMethod)) {
              return true;
            }

            PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType);
            PsiType typeAfterCast = toRaw(castSub.substitute(method.getReturnType()));
            PsiType typeDeclared = toRaw(plainResult.getSubstitutor().substitute(plainMethod.getReturnType()));
            return typeAfterCast != null && typeDeclared != null &&
                   !typeAfterCast.equals(typeDeclared) &&
                   ContainerUtil.exists(expectedTypes, et -> et.isAssignableFrom(typeAfterCast) && !et.isAssignableFrom(typeDeclared));
          }
        }
      }

      return containsMember(castType, o, true) && !containsMember(plainQualifier, o, true);
    }
    return false;
  }
private static boolean shouldCast(@NotNull LookupElement item,
                                    @NotNull PsiTypeLookupItem castTypeItem,
                                    @Nullable PsiType plainQualifier,
                                    @NotNull JavaCompletionProcessor processor,
                                    @NotNull Set<? extends PsiType> expectedTypes)