/**
  * Adds an extended formatting record to the list. If the XF record passed in has not been
  * initialized, its index is determined based on the xfRecords list, and this position is passed
  * to the XF records initialize method
  *
  * @param xf the xf record to add
  * @exception NumFormatRecordsException
  */
 public final void addStyle(XFRecord xf) throws NumFormatRecordsException {
   if (!xf.isInitialized()) {
     int pos = xfRecords.size();
     xf.initialize(pos, this, fonts);
     xfRecords.add(xf);
   } else {
     // The XF record has probably been read in.  If the index is greater
     // Than the size of the list, then it is not a preset format,
     // so add it
     if (xf.getXFIndex() >= xfRecords.size()) {
       xfRecords.add(xf);
     }
   }
 }
  /**
   * Rationalizes the cell formats. Duplicate formats are removed and the format indexed of the
   * cells adjusted accordingly
   */
  public IndexMapping rationalize(IndexMapping fontMapping, IndexMapping formatMapping) {
    // Update the index codes for the XF records using the format
    // mapping and the font mapping
    // at the same time
    XFRecord xfr = null;
    for (Iterator it = xfRecords.iterator(); it.hasNext(); ) {
      xfr = (XFRecord) it.next();

      if (xfr.getFormatRecord() >= customFormatStartIndex) {
        xfr.setFormatIndex(formatMapping.getNewIndex(xfr.getFormatRecord()));
      }

      xfr.setFontIndex(fontMapping.getNewIndex(xfr.getFontIndex()));
    }

    ArrayList newrecords = new ArrayList(minXFRecords);
    IndexMapping mapping = new IndexMapping(xfRecords.size());
    int numremoved = 0;

    // Copy across the fundamental styles
    for (int i = 0; i < minXFRecords; i++) {
      newrecords.add(xfRecords.get(i));
      mapping.setMapping(i, i);
    }

    // Iterate through the old list
    for (int i = minXFRecords; i < xfRecords.size(); i++) {
      XFRecord xf = (XFRecord) xfRecords.get(i);

      // Compare against formats already on the list
      boolean duplicate = false;
      for (Iterator it = newrecords.iterator(); it.hasNext() && !duplicate; ) {
        XFRecord xf2 = (XFRecord) it.next();
        if (xf2.equals(xf)) {
          duplicate = true;
          mapping.setMapping(i, mapping.getNewIndex(xf2.getXFIndex()));
          numremoved++;
          //          System.out.println("xf " +i + " is the same as " + xf2.getXFIndex());
        }
      }

      // If this format is not a duplicate then add it to the new list
      if (!duplicate) {
        newrecords.add(xf);
        mapping.setMapping(i, i - numremoved);
      }
    }

    // It is sufficient to merely change the xf index field on all XFRecords
    // In this case, CellValues which refer to defunct format records
    // will nevertheless be written out with the correct index number
    for (Iterator i = xfRecords.iterator(); i.hasNext(); ) {
      XFRecord xf = (XFRecord) i.next();
      xf.rationalize(mapping);
    }

    // Set the new list
    xfRecords = newrecords;

    //    System.out.println("Rationalize:  removed " + numremoved + " XF records");

    return mapping;
  }