protected TableRowElement getSubRowElement(int absRow, int subrow) {
        int relRow = absRow - getPageStart();
        checkRowBounds(relRow);

        /*
         * In most tables, the row element that represents the row object at the
         * specified index will be at the same index in the DOM. However, if the
         * user provides a TableBuilder that renders multiple rows per row value,
         * that will not be the case.
         *
         * We use a binary search to find the row, but we start at the index as that
         * is the most likely location.
         */
        NodeList<TableRowElement> rows = getTableBodyElement().getRows();
        int rowCount = rows.getLength();
        if (rowCount == 0) {
            return null;
        }

        int frameStart = 0;
        int frameEnd = rowCount - 1;
        int domIndex = Math.min(relRow, frameEnd);
        while (domIndex >= frameStart && domIndex <= frameEnd) {
            TableRowElement curRow = rows.getItem(domIndex);
            int rowValueIndex = tableBuilder.getRowValueIndex(curRow);
            if (rowValueIndex == absRow) {
                // Found a subrow in the row index.
                int subrowValueIndex = tableBuilder.getSubrowValueIndex(curRow);
                if (subrow != subrowValueIndex) {
                    // Shift to the correct subrow.
                    int offset = subrow - subrowValueIndex;
                    int subrowIndex = domIndex + offset;
                    if (subrowIndex >= rows.getLength()) {
                        // The subrow is out of range of the table.
                        return null;
                    }
                    curRow = rows.getItem(subrowIndex);
                    if (tableBuilder.getRowValueIndex(curRow) != absRow) {
                        // The "subrow" is actually part of the next row.
                        return null;
                    }
                }
                return curRow;
            } else if (rowValueIndex > absRow) {
                // Shift the frame to lower indexes.
                frameEnd = domIndex - 1;
            } else {
                // Shift the frame to higher indexes.
                frameStart = domIndex + 1;
            }

            // Move the dom index.
            domIndex = (frameStart + frameEnd) / 2;
        }

        // The element wasn't found.
        return null;
    }
Get a subrow element given the index of the row value and the sub row
index.

@param absRow the absolute row value index
@param subrow the index of the subrow beneath the row.
@return the row element, or null if not found
stroom-core-client-widget/src/main/java/com/google/gwt/user/cellview/client/AbstractCellTable.java