protected void finishTableRowLevelBox(final RenderBox box) {
    try {
      box.setCachedX(nodeContext.getX());
      box.setContentAreaX1(nodeContext.getX1());
      box.setContentAreaX2(nodeContext.getX2());

      if (box.getNodeType() != LayoutNodeTypes.TYPE_BOX_TABLE_CELL) {
        // break-marker boxes etc.
        box.setCachedWidth(resolveTableWidthOnFinish(box));
        nodeContext.updateParentX2(box.getCachedX2());
      } else {
        box.setCachedWidth(
            MinorAxisLayoutStepUtil.resolveNodeWidthOnFinish(
                box, nodeContext, isStrictLegacyMode()));

        final TableCellRenderBox cell = (TableCellRenderBox) box;
        final MinorAxisTableContext tableContext = getTableContext();
        final TableRenderBox table = tableContext.getTable();
        if (tableContext.isStructureValidated() == false) {
          table
              .getColumnModel()
              .updateCellSize(
                  cell.getColumnIndex(), cell.getColSpan(), box.getCachedWidth() - box.getInsets());
        }
        nodeContext.updateParentX2(box.getCachedX2());
      }
    } finally {
      nodeContext = nodeContext.pop();
    }
  }
  protected void finishTableSectionLevelBox(final RenderBox box) {
    try {
      box.setCachedX(nodeContext.getX());
      box.setContentAreaX1(nodeContext.getX1());
      box.setContentAreaX2(nodeContext.getX2());
      box.setCachedWidth(resolveTableWidthOnFinish(box));

      nodeContext.updateParentX2(box.getCachedX2());
    } finally {
      nodeContext = nodeContext.pop();
    }
  }
  protected void finishTableLevelBox(final RenderBox box) {
    try {
      if (checkCacheValid(box)) {
        nodeContext.updateParentX2(box.getCachedX2());
        return;
      }

      if (box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_COL_GROUP) {
        finishTableColGroup((TableColumnGroupNode) box);
      } else if (box.getNodeType() == LayoutNodeTypes.TYPE_BOX_TABLE_COL) {
        finishTableCol((TableColumnNode) box);
      } else {
        box.setCachedX(nodeContext.getX());
        box.setContentAreaX1(nodeContext.getX1());
        box.setContentAreaX2(nodeContext.getX2());
        box.setCachedWidth(resolveTableWidthOnFinish(box));
        nodeContext.updateParentX2(box.getCachedX2());
      }
    } finally {
      nodeContext = nodeContext.pop();
    }
  }
  protected void finishBlockLevelBox(final RenderBox box) {
    try {
      if (checkCacheValid(box)) {
        nodeContext.updateParentX2(box.getCachedX2());
        return;
      }

      box.setCachedX(nodeContext.getX());
      box.setContentAreaX1(nodeContext.getX1());
      box.setContentAreaX2(nodeContext.getX2());
      if (finishTableContext(box) == false) {
        box.setCachedWidth(
            MinorAxisLayoutStepUtil.resolveNodeWidthOnFinish(
                box, nodeContext, isStrictLegacyMode()));
      }
      nodeContext.updateParentX2(box.getCachedX2());

      finishParagraphBox(box);
    } finally {
      nodeContext = nodeContext.pop();
    }
  }
  protected void finishCanvasLevelBox(final RenderBox box) {
    try {
      if (checkCacheValid(box)) {
        nodeContext.updateParentX2(box.getCachedX2());
        return;
      }

      // make sure that the width takes all the borders and paddings into account.
      box.setCachedX(nodeContext.getX());
      box.setContentAreaX1(nodeContext.getX1());
      box.setContentAreaX2(nodeContext.getX2());
      if (finishTableContext(box) == false) {
        box.setCachedWidth(
            MinorAxisLayoutStepUtil.resolveNodeWidthOnFinish(
                box, nodeContext, isStrictLegacyMode()));
      }
      nodeContext.updateParentX2(box.getCachedX2());

      finishParagraphBox(box);
    } finally {
      nodeContext = nodeContext.pop();
    }
  }