/**
  * @return the shared ArrayRecord identified by (firstRow, firstColumn). never <code>null</code>.
  */
 public ArrayRecord getArrayRecord(int firstRow, int firstColumn) {
   for (ArrayRecord ar : _arrayRecords) {
     if (ar.isFirstCell(firstRow, firstColumn)) {
       return ar;
     }
   }
   return null;
 }
 /**
  * Removes the {@link ArrayRecord} for the cell group containing the specified cell. The caller
  * should clear (set blank) all cells in the returned range.
  *
  * @return the range of the array formula which was just removed. Never <code>null</code>.
  */
 public CellRangeAddress8Bit removeArrayFormula(int rowIndex, int columnIndex) {
   for (ArrayRecord ar : _arrayRecords) {
     if (ar.isInRange(rowIndex, columnIndex)) {
       _arrayRecords.remove(ar);
       return ar.getRange();
     }
   }
   String ref = new CellReference(rowIndex, columnIndex, false, false).formatAsString();
   throw new IllegalArgumentException(
       "Specified cell " + ref + " is not part of an array formula.");
 }
  /**
   * Gets the {@link SharedValueRecordBase} record if it should be encoded immediately after the
   * formula record contained in the specified {@link FormulaRecordAggregate} agg. Note - the shared
   * value record always appears after the first formula record in the group. For arrays and tables
   * the first formula is always the in the top left cell. However, since shared formula groups can
   * be sparse and/or overlap, the first formula may not actually be in the top left cell.
   *
   * @return the SHRFMLA, TABLE or ARRAY record for the formula cell, if it is the first cell of a
   *     table or array region. <code>null</code> if the formula cell is not shared/array/table, or
   *     if the specified formula is not the the first in the group.
   */
  public SharedValueRecordBase getRecordForFirstCell(FormulaRecordAggregate agg) {
    CellReference firstCell = agg.getFormulaRecord().getFormula().getExpReference();
    // perhaps this could be optimised by consulting the (somewhat unreliable) isShared flag
    // and/or distinguishing between tExp and tTbl.
    if (firstCell == null) {
      // not a shared/array/table formula
      return null;
    }

    int row = firstCell.getRow();
    int column = firstCell.getCol();
    if (agg.getRow() != row || agg.getColumn() != column) {
      // not the first formula cell in the group
      return null;
    }

    if (!_groupsBySharedFormulaRecord.isEmpty()) {
      SharedFormulaGroup sfg = findFormulaGroupForCell(firstCell);
      if (null != sfg) {
        return sfg.getSFR();
      }
    }

    // Since arrays and tables cannot be sparse (all cells in range participate)
    // The first cell will be the top left in the range.  So we can match the
    // ARRAY/TABLE record directly.

    for (TableRecord tr : _tableRecords) {
      if (tr.isFirstCell(row, column)) {
        return tr;
      }
    }
    for (ArrayRecord ar : _arrayRecords) {
      if (ar.isFirstCell(row, column)) {
        return ar;
      }
    }
    return null;
  }