/**
   * Rationalizes the display formats. Duplicate formats are removed and the format indices of the
   * cells adjusted accordingly. It is invoked immediately prior to writing writing out the sheet
   *
   * @param im the index mapping for the font rationalization
   */
  public IndexMapping rationalizeDisplayFormats() {
    ArrayList newformats = new ArrayList();
    int numremoved = 0;
    IndexMapping mapping = new IndexMapping(nextCustomIndexNumber);

    // Iterate through the old list
    Iterator i = formatsList.iterator();
    DisplayFormat df = null;
    DisplayFormat df2 = null;
    boolean duplicate = false;
    while (i.hasNext()) {
      df = (DisplayFormat) i.next();

      Assert.verify(!df.isBuiltIn());

      // Compare against formats already on the list
      Iterator i2 = newformats.iterator();
      duplicate = false;
      while (i2.hasNext() && !duplicate) {
        df2 = (DisplayFormat) i2.next();
        if (df2.equals(df)) {
          duplicate = true;
          mapping.setMapping(df.getFormatIndex(), mapping.getNewIndex(df2.getFormatIndex()));
          numremoved++;
        }
      }

      // If this format is not a duplicate then add it to the new list
      if (!duplicate) {
        newformats.add(df);
        int indexnum = df.getFormatIndex() - numremoved;
        if (indexnum > maxFormatRecordsIndex) {
          System.err.println("Warning:  too many number formats - using default format");
          indexnum = 0; // the default number format index
        }
        mapping.setMapping(df.getFormatIndex(), df.getFormatIndex() - numremoved);
      }
    }

    // Set the new list
    formatsList = newformats;

    // Update the index codes for the remaining formats
    i = formatsList.iterator();

    while (i.hasNext()) {
      df = (DisplayFormat) i.next();
      df.initialize(mapping.getNewIndex(df.getFormatIndex()));
    }

    return mapping;
  }
 public Object beanToEntity(@NotNull PropertyContainer entity, @NotNull Object bean) {
   Object value = readBeanValue(bean);
   if (converter != null && value != null) {
     value = converter.toNeo4j(value);
   }
   boolean updateIndex = false;
   Object oldValue = null;
   if (indexMapping != null) {
     oldValue = entity.getProperty(propertyName, null);
     updateIndex = !Neo4jUtils.equals(oldValue, value);
   }
   if (value != null) {
     entity.setProperty(propertyName, value);
   } else {
     entity.removeProperty(propertyName);
   }
   if (updateIndex) {
     indexMapping.update(entity, oldValue, value);
   }
   return value;
 }
  /**
   * 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;
  }