private static boolean canUseUpperBound(PsiTypeCastExpression cast) {
    PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(cast.getType());
    if (psiClass == null) return false;
    Set<PsiTypeParameter> parameters = Set.of(psiClass.getTypeParameters());
    if (parameters.isEmpty()) return false;
    PsiElement parent = PsiUtil.skipParenthesizedExprUp(cast.getParent());
    if (parent instanceof PsiReferenceExpression ref) {
      PsiElement target = ref.resolve();
      if (!(target instanceof PsiMember)) return false;
      PsiClass containingClass = ((PsiMember)target).getContainingClass();
      if (containingClass == null) return false;
      PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, psiClass, PsiSubstitutor.EMPTY);
      if (target instanceof PsiField) {
        PsiType type = substitutor.substitute(((PsiField)target).getType());
        PsiClass varType = PsiUtil.resolveClassInClassTypeOnly(type);
        return (varType instanceof PsiTypeParameter && parameters.contains(varType) && !PsiUtil.isAccessedForWriting(ref)) ||
               !PsiTypesUtil.mentionsTypeParameters(type, parameters);
      }
      if (target instanceof PsiMethod) {
        PsiMethodCallExpression call = ObjectUtils.tryCast(ref.getParent(), PsiMethodCallExpression.class);
        if (call == null) return false;
        if (!ExpressionUtils.isVoidContext(call)) {
          PsiType type = substitutor.substitute(((PsiMethod)target).getReturnType());
          PsiClass varType = PsiUtil.resolveClassInClassTypeOnly(type);
          if (!(varType instanceof PsiTypeParameter && parameters.contains(varType)) &&
              PsiTypesUtil.mentionsTypeParameters(type, parameters)) {
            return false;
          }
        }
        PsiParameterList parameterList = ((PsiMethod)target).getParameterList();
        for (PsiParameter parameter : parameterList.getParameters()) {
          if (parameter.isVarArgs() && call.getArgumentList().getExpressionCount() == parameterList.getParametersCount() - 1) {
            // No vararg parameters specified
            continue;
          }
          PsiType parameterType = parameter.getType();
          if (PsiTypesUtil.mentionsTypeParameters(parameterType, Predicates.alwaysTrue())) return false;
        }
        return true;
      }
    }
    return false;
  }
private static boolean canUseUpperBound(PsiTypeCastExpression cast)