/**
   * This method takes an object in its original state, and returns a new copy of the object with
   * the changes embodied in this DBObjectDeltaRec applied to it.
   */
  public DBObject applyDelta(DBObject original) {
    if (!original.getInvid().equals(invid)) {
      throw new IllegalArgumentException("Error, object identity mismatch");
    }

    /* - */

    DBObject copy;
    fieldDeltaRec fieldRec;
    Object value;

    /* -- */

    copy = new DBObject(original, null);

    // now process the fieldDeltaRec's.

    for (int i = 0; i < fieldRecs.size(); i++) {
      fieldRec = (fieldDeltaRec) fieldRecs.elementAt(i);

      // are we clearing this field?

      if (!fieldRec.vector && fieldRec.scalarValue == null) {
        copy.clearField(fieldRec.fieldcode);

        continue;
      }

      // are we doing a replace or add?

      if (!fieldRec.vector) {
        fieldRec.scalarValue.setOwner(copy);

        if (copy.getField(fieldRec.fieldcode) != null) {
          copy.replaceField(fieldRec.scalarValue);
        } else {
          copy.addField(fieldRec.scalarValue);
        }

        continue;
      }

      // ok, we must be doing a vector mod

      // remember that we are intentionally bypassing the DBField's
      // add/remove logic, as we assume that this DBObjectDeltaRec
      // was generated as a result of a properly checked operation.

      // Also, since we know that only string, invid, and IP fields
      // can be vectors, we don't have to worry about the password
      // and permission matrix special-case logic.

      DBField field = copy.retrieveField(fieldRec.fieldcode);

      if (fieldRec.addValues != null) {
        for (int j = 0; j < fieldRec.addValues.size(); j++) {
          value = fieldRec.addValues.elementAt(j);

          if (value instanceof IPwrap) {
            value = ((IPwrap) value).address;
          }

          field.getVectVal().addElement(value);
        }
      }

      if (fieldRec.delValues != null) {
        for (int j = 0; j < fieldRec.delValues.size(); j++) {
          value = fieldRec.delValues.elementAt(j);

          if (value instanceof IPwrap) {
            value = ((IPwrap) value).address;
          }

          field.getVectVal().removeElement(value);
        }
      }
    }

    return copy;
  }