private Fragment getEarliestBunchInIntervalImpl(long earliestRevision,
                                                  final long oldestRevision,
                                                  final int desirableSize,
                                                  final boolean includeYoungest,
                                                  final boolean includeOldest, final long earliestToTake) throws VcsException {
    if ((myEarliestRevisionWasAccessed) || ((oldestRevision == myYoungestRevision) && ((! includeYoungest) || (! includeOldest)))) {
      return null;
    }
    final Revision youngRevision = (earliestRevision == -1) ? Revision.HEAD : Revision.of(earliestRevision);

    final Ref<List<CommittedChangeList>> refToList = new Ref<>();
    final Ref<VcsException> exceptionRef = new Ref<>();

    final Runnable loader = () -> {
      try {
        refToList
          .set(myLoader.loadInterval(youngRevision, Revision.of(oldestRevision), desirableSize, includeYoungest, includeOldest));
      }
      catch (VcsException e) {
        exceptionRef.set(e);
      }
    };

    final Application application = ApplicationManager.getApplication();
    if (application.isUnitTestMode() || ! application.isDispatchThread()) {
      loader.run();
    } else {
      ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
        final ProgressIndicator ind = ProgressManager.getInstance().getProgressIndicator();
        if (ind != null) {
          ind.setText(SvnBundle.message("progress.live.provider.loading.revisions.details.text"));
        }
        loader.run();
      }, SvnBundle.message("progress.live.provider.loading.revisions.text"), false, myVcs.getProject());
    }

    if (!exceptionRef.isNull()) {
      final VcsException e = exceptionRef.get();
      if (isElementNotFound(e)) {
        // occurs when target URL is deleted in repository
        // try to find latest existent revision. expensive ...
        final LatestExistentSearcher searcher = new LatestExistentSearcher(oldestRevision, myYoungestRevision, (oldestRevision != 0),
                                                                           myVcs, myLocation.toSvnUrl(), myRepositoryUrl);
        final long existent = searcher.getLatestExistent();
        if ((existent == -1) || (existent == earliestRevision)) {
          myEarliestRevisionWasAccessed = true;
          return null;
        }
        return getEarliestBunchInIntervalImpl(existent, oldestRevision, includeYoungest ? desirableSize : (desirableSize + 1), true,
                                              includeOldest,
                                              Math.min(existent, earliestRevision));
      }
      throw e;
    }

    final List<CommittedChangeList> list = refToList.get();
    if (list.isEmpty()) {
      myEarliestRevisionWasAccessed = (oldestRevision == 0);
      return null;
    }
    if (earliestToTake > 0) {
      for (Iterator<CommittedChangeList> iterator = list.iterator(); iterator.hasNext(); ) {
        final CommittedChangeList changeList = iterator.next();
        if (changeList.getNumber() > earliestToTake) iterator.remove();
      }
    }
    myEarliestRevisionWasAccessed = (oldestRevision == 0) && ((list.size() + ((! includeOldest) ? 1 : 0) + ((! includeYoungest) ? 1 : 0)) < desirableSize);
    return new Fragment(Origin.LIVE, list, true, true, null);
  }
private Fragment getEarliestBunchInIntervalImpl(long earliestRevision,
                                                  final long oldestRevision,
                                                  final int desirableSize,
                                                  final boolean includeYoungest,
                                                  final boolean includeOldest, final long earliestToTake)