/**
   * Process a (Item) section.
   *
   * <p>Each section has a heading row that is used to identify what field each cell relates to in
   * the domain object.
   *
   * @param section
   * @return
   */
  protected boolean processSectionData(SpreadsheetSection section) {
    List<SpreadsheetRow> rows = section.getSectionRows();
    currentSheetName = section.getSheetName();

    if (section.getSectionHeadingString().startsWith(PAGE_ITEMS_UPPER)) {
      currentPage = new ExtractItems(application, currentPage).processSectionData(section);
      if (currentPage == null) {
        logger.debug("Warning: no current page returned for section. " + section.toString());
        return true;
      }
      return true;
    }

    for (Iterator<SpreadsheetRow> rowIter = rows.iterator(); rowIter.hasNext(); ) {
      SpreadsheetRow spreadsheetRow = (SpreadsheetRow) rowIter.next();
      if (spreadsheetRow.getRowItems().size() == 0) {
        continue;
      }
      if (section.getSectionHeadingString().startsWith(InformerSpreadsheetLoader.SHEET_END)) {
        // ignore the rest of the rows, although should never have got here
        logger.debug("Did not expect to be processing a Sheet End section - ignoring!");
        break;
      }
    }

    return true;
  }
  /**
   * Identify the Page related sections (Item) that we want to process, and initiate that.
   *
   * @return true if all sections processed OK
   */
  public boolean processPages() {
    for (Iterator<SpreadsheetSection> iterator = data.iterator(); iterator.hasNext(); ) {
      SpreadsheetSection section = (SpreadsheetSection) iterator.next();
      if (section.isProcessed()) {
        continue;
      }

      if (!processSectionData(section)) {
        logger.debug(
            "Failed to process section "
                + section.getSectionHeadingString()
                + " for sheet "
                + section.getSheetName());
        return false;
      }
    }

    return true;
  }