private LayoutController findParentCell() {
   LayoutController parent = getParent();
   while (parent != null) {
     final Object node = parent.getNode();
     if (node instanceof Element) {
       final Element element = (Element) node;
       if (OfficeNamespaces.TABLE_NS.equals(element.getNamespace())
           && "table-cell".equals(element.getType())) {
         return parent;
       }
     }
     parent = parent.getParent();
   }
   return null;
 }
  protected ImageElementContext createContext() {
    if (context == null) {

      // Step 1: Find the parent cell.
      final LayoutController cellController = findParentCell();
      if (cellController == null) {
        LOGGER.warn("Image is not contained in a table. Unable to calculate the image-size.");
        return null;
      }
      final Element tableCell = (Element) cellController.getNode();
      final int rowSpan =
          TextUtilities.parseInt(
              (String) tableCell.getAttribute(OfficeNamespaces.TABLE_NS, "number-rows-spanned"), 1);
      final int colSpan =
          TextUtilities.parseInt(
              (String) tableCell.getAttribute(OfficeNamespaces.TABLE_NS, "number-columns-spanned"),
              1);
      if (rowSpan < 1 || colSpan < 1) {
        LOGGER.warn("Rowspan or colspan for image-size calculation was invalid.");
        return null;
      }

      final LayoutController rowController = cellController.getParent();
      if (rowController == null) {
        LOGGER.warn("Table-Cell has no parent. Unable to calculate the image-size.");
        return null;
      }
      final Section tableRow = (Section) rowController.getNode();
      // we are now making the assumption, that the row is a section, that contains the table-cell.
      // This breaks the ability to return nodes or to construct reports on the fly, but the
      // OO-report format
      // is weird anyway and won't support such advanced techniques for the next few centuries...
      final int columnPos = findNodeInSection(tableRow, tableCell, OfficeToken.COVERED_TABLE_CELL);
      if (columnPos == -1) {
        LOGGER.warn(
            "Table-Cell is not a direct child of the table-row. Unable to calculate the image-size.");
        return null;
      }

      final LayoutController tableController = rowController.getParent();
      if (tableController == null) {
        LOGGER.warn("Table-Row has no Table. Unable to calculate the image-size.");
        return null;
      }

      final Section table = (Section) tableController.getNode();
      // ok, we got a table, so as next we have to search for the columns now.
      final Section columns =
          (Section) table.findFirstChild(OfficeNamespaces.TABLE_NS, OfficeToken.TABLE_COLUMNS);
      if (columns.getNodeCount() <= columnPos + colSpan) {
        // the colspan is to large. The table definition is therefore invalid. We do not try to fix
        // this.
        LOGGER.warn(
            "The Table's defined columns do not match the col-span or col-position. Unable to calculate the image-size.");
        return null;
      }

      final ImageElementContext context = new ImageElementContext(colSpan, rowSpan);
      addColumnStyles(context, columns, columnPos, colSpan);
      // finally search the styles for the row now.
      final int rowPos = findNodeInSection(table, tableRow, null);
      if (rowPos == -1) {
        LOGGER.warn(
            "Table-Cell is not a direct child of the table-row. Unable to calculate the image-size.");
        return null;
      }

      addRowStyles(context, table, rowPos, rowSpan);
      this.context = context;
    }
    return this.context;
  }