/**
   * Compare the attributes. Return true if they are alike. Assume the passed-in attributes are
   * non-null.
   */
  private boolean compareAttributeValues(
      Object collection1, Object collection2, AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();

    if (cp.sizeFor(collection1) != cp.sizeFor(collection2)) {
      return false;
    }

    // if they are both empty, go no further...
    if (cp.sizeFor(collection1) == 0) {
      return true;
    }

    if (cp.hasOrder()) {
      return this.compareAttributeValuesWithOrder(collection1, collection2, session);
    } else {
      return this.compareAttributeValuesWithoutOrder(collection1, collection2, session);
    }
  }
  /**
   * INTERNAL: Build and return the change record that results from comparing the two collection
   * attributes.
   */
  public ChangeRecord compareForChange(
      Object clone, Object backup, ObjectChangeSet owner, AbstractSession session) {
    ContainerPolicy cp = this.getContainerPolicy();
    Object cloneCollection = this.getRealCollectionAttributeValueFromObject(clone, session);

    Object backupCollection = null;
    if (owner.isNew()) {
      backupCollection = cp.containerInstance(1);
    } else {
      backupCollection = this.getRealCollectionAttributeValueFromObject(backup, session);
    }

    if (cp.hasOrder()) {
      return this.compareAttributeValuesForChangeWithOrder(
          cloneCollection, backupCollection, owner, session);
    } else {
      return this.compareAttributeValuesForChangeWithoutOrder(
          cloneCollection, backupCollection, owner, session);
    }
  }