protected boolean startTableRowLevelBox(final RenderBox box) {
    if (lineBreakState.isInsideParagraph()) {
      // The break-state exists only while we are inside of an paragraph
      // and suspend can only happen on inline elements.
      // A block-element inside a paragraph cannot be (and if it does, it is
      // a bug)
      throw new IllegalStateException("This cannot be.");
    }

    nodeContext = nodeContextPool.createContext(box, nodeContext, false);

    if (box.getNodeType() != LayoutNodeTypes.TYPE_BOX_TABLE_CELL) {
      startTableSectionOrRow(box);
      return true;
    }

    final MinorAxisTableContext tableContext = getTableContext();
    final TableCellRenderBox tableCellRenderBox = (TableCellRenderBox) box;

    // This is slightly different for table cells ...
    final int columnIndex = tableCellRenderBox.getColumnIndex();
    final TableColumnModel columnModel = tableContext.getColumnModel();

    // cell-size does not include border spacing
    final long startOfRowX = nodeContext.getParentX1();

    final long x = startOfRowX + columnModel.getCellPosition(columnIndex);
    final long insetsLeft = Math.max(box.getInsetsLeft(), columnModel.getBorderSpacing() / 2);
    final long insetsRight = Math.max(box.getInsetsRight(), columnModel.getBorderSpacing() / 2);
    final long width = computeCellWidth(tableCellRenderBox);
    nodeContext.setArea(x, insetsLeft, insetsRight, width);
    return true;
  }
  protected boolean startRowLevelBox(final RenderBox box) {
    if (lineBreakState.isInsideParagraph()) {
      // The break-state exists only while we are inside of an paragraph
      // and suspend can only happen on inline elements.
      // A block-element inside a paragraph cannot be (and if it does, it is
      // a bug)
      throw new IllegalStateException("This cannot be.");
    }

    nodeContext = nodeContextPool.createContext(box, nodeContext, false);

    if (checkCacheValid(box)) {
      return false;
    }

    startTableContext(box);

    final long x = computeRowPosition(box);
    final long left = box.getInsetsLeft();
    final long right = box.getInsetsRight();
    final long width = MinorAxisLayoutStepUtil.resolveNodeWidthOnStart(box, nodeContext, x);
    assert width >= 0;

    nodeContext.setArea(x, left, right, width);

    if (startParagraphBox(box) == false) {
      return false;
    }

    return true;
  }
  protected boolean startBlockLevelBox(final RenderBox box) {
    if (lineBreakState.isInsideParagraph()) {
      throw new InvalidReportStateException(
          "A block-level element inside a paragraph is not allowed.");
    }

    nodeContext = nodeContextPool.createContext(box, nodeContext, true);

    if (checkCacheValid(box)) {
      return false;
    }

    startTableContext(box);

    final long x = nodeContext.getParentX1();
    final long left = box.getInsetsLeft();
    final long right = box.getInsetsRight();
    final long width = MinorAxisLayoutStepUtil.resolveNodeWidthOnStart(box, nodeContext, x);

    assert width >= 0;

    nodeContext.setArea(x, left, right, width);

    if (startParagraphBox(box) == false) {
      return false;
    }

    return true;
  }
  protected boolean startTableColGroupLevelBox(final RenderBox box) {
    nodeContext = nodeContextPool.createContext(box, nodeContext, false);

    if (checkCacheValid(box)) {
      return false;
    }

    if (box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_COL) {
      startTableCol((TableColumnNode) box);
    }
    return true;
  }
  protected boolean startTableSectionLevelBox(final RenderBox box) {
    if (lineBreakState.isInsideParagraph()) {
      // The break-state exists only while we are inside of an paragraph
      // and suspend can only happen on inline elements.
      // A block-element inside a paragraph cannot be (and if it does, it is
      // a bug)
      throw new IllegalStateException("This cannot be.");
    }

    nodeContext = nodeContextPool.createContext(box, nodeContext, true);

    startTableSectionOrRow(box);
    return true;
  }
  // Table-sections or auto-boxes masking as tables (treated as table-sections nonetheless).
  protected boolean startTableLevelBox(final RenderBox box) {
    if (lineBreakState.isInsideParagraph()) {
      // The break-state exists only while we are inside of an paragraph
      // and suspend can only happen on inline elements.
      // A block-element inside a paragraph cannot be (and if it does, it is
      // a bug)
      throw new IllegalStateException("This cannot be.");
    }

    nodeContext = nodeContextPool.createContext(box, nodeContext, true);

    if (checkCacheValid(box)) {
      return false;
    }

    if (box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_COL_GROUP) {
      startTableColGroup((TableColumnGroupNode) box);
    } else if (box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_COL) {
      startTableCol((TableColumnNode) box);
    } else {
      startTableSectionOrRow(box);
    }
    return true;
  }