private static boolean hasUnresolvedComponentRecursively(@Nullable PsiType psiType, @NotNull HashSet<PsiClass> visited) {
    if (psiType == null) return false;
    PsiType type = psiType.getDeepComponentType();
    if (isUnresolvedClassType(psiType)) {
      return true;
    }
    if (type instanceof PsiClassType) {
      PsiClass psiClass = PsiUtil.resolveClassInClassTypeOnly(type);
      if (psiClass != null && !visited.add(psiClass)) {
        return false;
      }
      for (PsiType parameter : ((PsiClassType)type).getParameters()) {
        if (hasUnresolvedComponentRecursively(parameter, visited)) {
          return true;
        }
      }
    }
    if (type instanceof PsiWildcardType) {
      return hasUnresolvedComponentRecursively(((PsiWildcardType)type).getBound(), visited);
    }
    if (type instanceof PsiCapturedWildcardType) {
      return hasUnresolvedComponentRecursively(((PsiCapturedWildcardType)type).getLowerBound(), visited) ||
             hasUnresolvedComponentRecursively(((PsiCapturedWildcardType)type).getUpperBound(), visited);
    }
    return false;
  }
private static boolean hasUnresolvedComponentRecursively(@Nullable PsiType psiType, @NotNull HashSet<PsiClass> visited)