/** INTERNAL: */
  public Vector getForeignKeyRows(AbstractRecord row) {
    Vector subRows = new Vector();
    if (getForeignKeyGroupingElement() == null) {
      if (this.getSourceForeignKeyFields().size() > 0) {
        Object values = row.getValues((DatabaseField) this.getSourceForeignKeyFields().get(0));

        if (values != null) {
          if (values instanceof Vector) {
            int valuesSize = ((Vector) values).size();
            for (int j = 0; j < valuesSize; j++) {
              XMLRecord newRecord = new DOMRecord("test");
              newRecord.setSession(((XMLRecord) row).getSession());
              newRecord.put(this.getSourceForeignKeyFields().get(0), ((Vector) values).get(j));
              subRows.add(newRecord);
            }
          } else {
            XMLRecord newRecord = new DOMRecord("test");
            newRecord.setSession(((XMLRecord) row).getSession());
            newRecord.put(getSourceForeignKeyFields().get(0), values);
            subRows.add(newRecord);
          }
        }
      }
    } else {
      subRows = (Vector) row.getValues(getForeignKeyGroupingElement());
    }
    return subRows;
  }
  /**
   * INTERNAL: Get the appropriate attribute value from the object and put it in the appropriate
   * field of the database row. Loop through the reference objects and extract the primary keys and
   * put them in the vector of "nested" rows.
   */
  public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session) {
    if (!isForeignKeyRelationship) {
      return;
    }

    if (((getSourceForeignKeysToTargetKeys()) == null)
        || (getSourceForeignKeysToTargetKeys().size() == 0)) {
      return;
    }

    if (this.isReadOnly()) {
      return;
    }

    AbstractRecord referenceRow =
        this.getIndirectionPolicy().extractReferenceRow(this.getAttributeValueFromObject(object));
    if (referenceRow != null) {
      // the reference objects have not been instantiated - use the value from the original row
      if (getForeignKeyGroupingElement() != null) {
        row.put(
            this.getForeignKeyGroupingElement(),
            referenceRow.getValues(this.getForeignKeyGroupingElement()));
      } else if (getSourceForeignKeyFields().size() > 0) {
        DatabaseField foreignKeyField = (DatabaseField) getSourceForeignKeyFields().get(0);
        row.put(foreignKeyField, referenceRow.getValues(foreignKeyField));
      }
      return;
    }

    ContainerPolicy cp = this.getContainerPolicy();

    // extract the keys from the objects
    Object attributeValue = this.getRealCollectionAttributeValueFromObject(object, session);
    Vector nestedRows = new Vector(cp.sizeFor(attributeValue));

    if (getForeignKeyGroupingElement() != null) {
      for (Object iter = cp.iteratorFor(attributeValue); cp.hasNext(iter); ) {
        XMLRecord nestedRow =
            this.extractKeyRowFromReferenceObject(cp.next(iter, session), session, (XMLRecord) row);
        nestedRows.addElement(nestedRow);
      }
      row.add(this.getForeignKeyGroupingElement(), nestedRows);
    } else {
      DatabaseField singleField = (DatabaseField) getSourceForeignKeyFields().get(0);
      DatabaseField pkField = (DatabaseField) getSourceForeignKeysToTargetKeys().get(singleField);
      for (Object iter = cp.iteratorFor(attributeValue); cp.hasNext(iter); ) {
        Object singleValue =
            getReferenceDescriptor()
                .getObjectBuilder()
                .extractValueFromObjectForField(cp.next(iter, session), pkField, session);
        row.add(singleField, singleValue);
      }
    }
  }