/**
   * 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: Merge changes from the source to the target object. Simply replace the entire target
   * collection.
   */
  public void mergeIntoObject(
      Object target, boolean isTargetUnInitialized, Object source, MergeManager mergeManager) {
    ContainerPolicy cp = this.getContainerPolicy();
    AbstractSession session = mergeManager.getSession();

    Object sourceCollection = this.getRealCollectionAttributeValueFromObject(source, session);
    Object targetCollection = cp.containerInstance(cp.sizeFor(sourceCollection));

    for (Object iter = cp.iteratorFor(sourceCollection); cp.hasNext(iter); ) {
      Object targetElement = this.buildElementFromElement(cp.next(iter, session), mergeManager);
      cp.addInto(targetElement, targetCollection, session);
    }

    // reset the attribute to allow for set method to re-morph changes if the collection is not
    // being stored directly
    this.setRealAttributeValueInObject(target, targetCollection);
  }