public <T> void tryJumpTo(@NotNull T commitId,
                            @NotNull BiFunction<? super VisiblePack, ? super T, Integer> rowGetter,
                            @NotNull SettableFuture<JumpResult> future,
                            boolean focus) {
    if (future.isCancelled()) return;

    int result = rowGetter.apply(myVisiblePack, commitId);
    if (result >= 0) {
      getTable().jumpToRow(result, focus);
      future.set(JumpResult.SUCCESS);
    }
    else if (VcsLogUtil.canRequestMore(myVisiblePack)) {
      VcsLogUtil.requestToLoadMore(this, () -> tryJumpTo(commitId, rowGetter, future, focus));
    }
    else if (myLogData.getDataPack() != myVisiblePack.getDataPack() ||
             (myVisiblePack.canRequestMore() && VcsLogUtil.isMoreRequested(myVisiblePack))) {
      VcsLogUtil.invokeOnChange(this, () -> tryJumpTo(commitId, rowGetter, future, focus));
    }
    else if (myVisiblePack.getDataPack() instanceof DataPack.ErrorDataPack ||
             myVisiblePack instanceof VisiblePack.ErrorVisiblePack) {
      future.set(JumpResult.fromInt(result));
    }
    else if (!myVisiblePack.isFull()) {
      VcsLogUtil.invokeOnChange(this, () -> tryJumpTo(commitId, rowGetter, future, focus));
    }
    else {
      future.set(JumpResult.fromInt(result));
    }
  }
public <T> void tryJumpTo(@NotNull T commitId,
                            @NotNull BiFunction<? super VisiblePack, ? super T, Integer> rowGetter,
                            @NotNull SettableFuture<JumpResult> future,
                            boolean focus)