/**
   * Sees if the extended formatting record at the specified position represents a date. First
   * checks against the built in formats, and then checks against the hash map of FormatRecords
   *
   * @param pos the xf format index
   * @return TRUE if this format index is formatted as a Date
   */
  public final boolean isDate(int pos) {
    XFRecord xfr = (XFRecord) xfRecords.get(pos);

    if (xfr.isDate()) {
      return true;
    }

    FormatRecord fr = (FormatRecord) formats.get(new Integer(xfr.getFormatRecord()));

    return fr == null ? false : fr.isDate();
  }
 /**
  * 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);
     }
   }
 }
  /**
   * Gets the NumberFormat used to format the cell.
   *
   * @param pos the xf format index
   * @return the DateFormat object used to format the date in the original excel cell
   */
  public final NumberFormat getNumberFormat(int pos) {
    XFRecord xfr = (XFRecord) xfRecords.get(pos);

    if (xfr.isNumber()) {
      return xfr.getNumberFormat();
    }

    FormatRecord fr = (FormatRecord) formats.get(new Integer(xfr.getFormatRecord()));

    if (fr == null) {
      return null;
    }

    return fr.isNumber() ? fr.getNumberFormat() : null;
  }
  /**
   * 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;
  }