public static @NotNull <V> Outcome<V> provideDataWithProgressSynchronously(
    @Nullable Project project,
    @NotNull @NlsContexts.ProgressTitle String progressTitle,
    final @NotNull @NlsContexts.ProgressText String actionShortDescription,
    final @NotNull Callable<? extends V> supplier,
    @Nullable Producer<Boolean> tryAgainProvider) {
    int attemptNumber = 1;
    while (true) {
      final Ref<V> dataRef = Ref.create(null);
      final Ref<Exception> innerExceptionRef = Ref.create(null);
      boolean completed = ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
        ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
        indicator.setText(actionShortDescription);
        try {
          V data = supplier.call();
          dataRef.set(data);
        }
        catch (Exception ex) {
          innerExceptionRef.set(ex);
        }
      }, progressTitle, true, project);
      if (!completed) {
        return Outcome.createAsCancelled();
      }
      Exception latestInnerException = innerExceptionRef.get();
      if (latestInnerException == null) {
        return Outcome.createNormal(dataRef.get());
      }
      LOG.info("[attempt#" + attemptNumber + "] Cannot '" + actionShortDescription + "'");
      boolean onceMore = false;
      if (tryAgainProvider != null) {
        onceMore = Boolean.TRUE.equals(tryAgainProvider.produce());
      }
      if (!onceMore) {
        return Outcome.createAsException(latestInnerException);
      }
      attemptNumber++;
    }
  }
public static @NotNull <V> Outcome<V> provideDataWithProgressSynchronously(
    @Nullable Project project,
    @NotNull @NlsContexts.ProgressTitle String progressTitle,
    final @NotNull @NlsContexts.ProgressText String actionShortDescription,
    final @NotNull Callable<? extends V> supplier,
    @Nullable Producer<Boolean> tryAgainProvider)