/**
   * INTERNAL: This methods clones all the fields and ensures that each collection refers to the
   * same clones.
   */
  @Override
  public Object clone() {
    VariableOneToOneMapping clone = (VariableOneToOneMapping) super.clone();
    Map setOfKeys = new HashMap(getSourceToTargetQueryKeyNames().size());
    Map sourceToTarget = new HashMap(getSourceToTargetQueryKeyNames().size());
    Vector foreignKeys =
        org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance(
            getForeignKeyFields().size());

    if (getTypeField() != null) {
      clone.setTypeField((DatabaseField) this.getTypeField().clone());
    }

    for (Iterator enumtr = getSourceToTargetQueryKeyNames().keySet().iterator();
        enumtr.hasNext(); ) {
      // Clone the SourceKeyFields
      DatabaseField field = (DatabaseField) enumtr.next();
      DatabaseField clonedField = (DatabaseField) field.clone();
      setOfKeys.put(field, clonedField);
      // on the next line I'm cloning the query key names
      sourceToTarget.put(clonedField, getSourceToTargetQueryKeyNames().get(field));
    }

    for (Enumeration enumtr = getForeignKeyFields().elements(); enumtr.hasMoreElements(); ) {
      DatabaseField field = (DatabaseField) enumtr.nextElement();
      foreignKeys.addElement(setOfKeys.get(field));
    }
    clone.setSourceToTargetQueryKeyFields(sourceToTarget);
    clone.setForeignKeyFields(foreignKeys);
    clone.setTypeIndicatorTranslation(new HashMap(this.getTypeIndicatorTranslation()));
    return clone;
  }
  /**
   * INTERNAL: Return the classification for the field contained in the mapping. This is used to
   * convert the row value to a consistent java value.
   */
  @Override
  public Class getFieldClassification(DatabaseField fieldToClassify) {
    if ((getTypeField() != null) && (fieldToClassify.equals(getTypeField()))) {
      return getTypeField().getType();
    }

    String queryKey = (String) getSourceToTargetQueryKeyNames().get(fieldToClassify);
    if (queryKey == null) {
      return null;
    }
    // Search any of the implementor descriptors for a mapping for the query-key.
    Iterator iterator =
        getReferenceDescriptor().getInterfacePolicy().getChildDescriptors().iterator();
    if (iterator.hasNext()) {
      ClassDescriptor firstChild = (ClassDescriptor) iterator.next();
      DatabaseMapping mapping = firstChild.getObjectBuilder().getMappingForAttributeName(queryKey);
      if ((mapping != null) && (mapping.isDirectToFieldMapping())) {
        return ((AbstractDirectMapping) mapping).getAttributeClassification();
      }
      QueryKey targetQueryKey = firstChild.getQueryKeyNamed(queryKey);
      if ((targetQueryKey != null) && (targetQueryKey.isDirectQueryKey())) {
        return firstChild
            .getObjectBuilder()
            .getFieldClassification(((DirectQueryKey) targetQueryKey).getField());
      }
    }
    return null;
  }