public Selection(@NotNull VcsLogGraphTable table) {
      myTable = table;
      List<Integer> selectedRows = ContainerUtil.sorted(toList(myTable.getSelectedRows()));
      Couple<Integer> visibleRows = ScrollingUtil.getVisibleRows(myTable);
      myScrollToTop = visibleRows.first - 1 == 0;

      VisibleGraph<Integer> graph = myTable.getVisibleGraph();

      mySelectedCommits = new TIntHashSet();

      Integer visibleSelectedCommit = null;
      Integer delta = null;
      for (int row : selectedRows) {
        if (row < graph.getVisibleCommitCount()) {
          Integer commit = graph.getRowInfo(row).getCommit();
          mySelectedCommits.add(commit);
          if (visibleRows.first - 1 <= row
              && row <= visibleRows.second
              && visibleSelectedCommit == null) {
            visibleSelectedCommit = commit;
            delta = myTable.getCellRect(row, 0, false).y - myTable.getVisibleRect().y;
          }
        }
      }
      if (visibleSelectedCommit == null && visibleRows.first - 1 >= 0) {
        visibleSelectedCommit = graph.getRowInfo(visibleRows.first - 1).getCommit();
        delta = myTable.getCellRect(visibleRows.first - 1, 0, false).y - myTable.getVisibleRect().y;
      }

      myVisibleSelectedCommit = visibleSelectedCommit;
      myDelta = delta;
    }
    @NotNull
    private Pair<TIntHashSet, Integer> findRowsToSelectAndScroll(
        @NotNull GraphTableModel model, @NotNull VisibleGraph<Integer> visibleGraph) {
      TIntHashSet rowsToSelect = new TIntHashSet();

      if (model.getRowCount() == 0) {
        // this should have been covered by facade.getVisibleCommitCount,
        // but if the table is empty (no commits match the filter), the GraphFacade is not updated,
        // because it can't handle it
        // => it has previous values set.
        return Pair.create(rowsToSelect, null);
      }

      Integer rowToScroll = null;
      for (int row = 0;
          row < visibleGraph.getVisibleCommitCount()
              && (rowsToSelect.size() < mySelectedCommits.size() || rowToScroll == null);
          row++) { // stop iterating if found all hashes
        int commit = visibleGraph.getRowInfo(row).getCommit();
        if (mySelectedCommits.contains(commit)) {
          rowsToSelect.add(row);
        }
        if (myVisibleSelectedCommit != null && myVisibleSelectedCommit == commit) {
          rowToScroll = row;
        }
      }
      return Pair.create(rowsToSelect, rowToScroll);
    }
  private VcsLogHighlighter.VcsCommitStyle getStyle(
      int row, int column, String text, boolean hasFocus, final boolean selected) {
    Component dummyRendererComponent =
        myDummyRenderer.getTableCellRendererComponent(this, text, selected, hasFocus, row, column);

    VisibleGraph<Integer> visibleGraph = getVisibleGraph();
    if (row < 0 || row >= visibleGraph.getVisibleCommitCount()) {
      LOG.error(
          "Visible graph has "
              + visibleGraph.getVisibleCommitCount()
              + " commits, yet we want row "
              + row);
      return VcsCommitStyleFactory.createStyle(
          dummyRendererComponent.getForeground(),
          dummyRendererComponent.getBackground(),
          VcsLogHighlighter.TextStyle.NORMAL);
    }

    final RowInfo<Integer> rowInfo = visibleGraph.getRowInfo(row);

    VcsLogHighlighter.VcsCommitStyle defaultStyle =
        VcsCommitStyleFactory.createStyle(
            rowInfo.getRowType() == RowType.UNMATCHED
                ? JBColor.GRAY
                : dummyRendererComponent.getForeground(),
            dummyRendererComponent.getBackground(),
            VcsLogHighlighter.TextStyle.NORMAL);

    List<VcsLogHighlighter.VcsCommitStyle> styles =
        ContainerUtil.map(
            myHighlighters,
            new Function<VcsLogHighlighter, VcsLogHighlighter.VcsCommitStyle>() {
              @Override
              public VcsLogHighlighter.VcsCommitStyle fun(VcsLogHighlighter highlighter) {
                return highlighter.getStyle(rowInfo.getCommit(), selected);
              }
            });

    return VcsCommitStyleFactory.combine(ContainerUtil.append(styles, defaultStyle));
  }