public FieldMap build(ClassMap classMap, BeanContainer beanContainer, DestBeanCreator destBeanCreator, PropertyDescriptorFactory propertyDescriptorFactory) {
        if (a == null || b == null) {
            throw new MappingException("Field name can not be empty");
        }

        DozerField aField = a.convert();
        DozerField bField = b.convert();

        FieldMap fieldMap = resolveFieldMapType(classMap, aField, bField, beanContainer, destBeanCreator, propertyDescriptorFactory);
        fieldMap.setSrcField(aField);
        fieldMap.setDestField(bField);
        if (type != null) {
            fieldMap.setType(MappingDirection.valueOf(type.value()));
        }

        if (relationshipType != null) {
            fieldMap.setRelationshipType(RelationshipType.valueOf(relationshipType.value()));
        }

        fieldMap.setRemoveOrphans(removeOrphans == null ? false : removeOrphans);

        HintContainer aHintContainer = getHintContainer(aHint, beanContainer);
        if (aHintContainer != null) {
            fieldMap.setSrcHintContainer(aHintContainer);
        }

        HintContainer bHintContainer = getHintContainer(bHint, beanContainer);
        if (bHintContainer != null) {
            fieldMap.setDestHintContainer(bHintContainer);
        }

        HintContainer aDeepHintContainer = getHintContainer(aDeepIndexHint, beanContainer);
        if (aDeepHintContainer != null) {
            fieldMap.setSrcDeepIndexHintContainer(aDeepHintContainer);
        }

        HintContainer bDeepHintContainer = getHintContainer(bDeepIndexHint, beanContainer);
        if (bDeepHintContainer != null) {
            fieldMap.setDestDeepIndexHintContainer(bDeepHintContainer);
        }

        if (copyByReference != null) {
            fieldMap.setCopyByReference(copyByReference);
        }

        fieldMap.setMapId(mapId);
        fieldMap.setCustomConverter(customConverter);
        fieldMap.setCustomConverterId(customConverterId);
        fieldMap.setCustomConverterParam(customConverterParam);

        return fieldMap;
    }
Specifies a custom field mapping. Fields that share the same attribute name do not need to be defined.
Dozer automatically maps fields that match on attribute name. All Field Mapping definitions are bi-directional
by default.
Global configuration, Mapping, and ClassDefinition element values are inherited.
<p>
Hints are used for mapping Collection types. A hint indicates which type of destination object should be created
and added to the
destination Collection.
<p>
Required Attributes:
<p>
Optional Attributes:
<p>
relationship-type For collections, indicates whether to add to existing values or to always replace any existing
entries
<p>
remove-orphans For collections, indicates whether items that did not exist in the source collection should be
removed from the destination collection.
<p>
type Indicates whether this mapping is bi-directional or only one-way. Typically this will be set to bi-directional. The default is "bi-directional".
<p>
map-id The id that uniquely identifies this mapping definition. This typically will not be specified.
You would only need to specify this for only need this for special context based mapping
and when mapping between Map objects and Custom Data Objects.
<p>
copy-by-reference Indicates whether the source field value is copied by reference or by value when populating the destination field. The default value is "false"
<p>
custom-converter Indicates that a specific custom converter should be used for mapping this field. Typically
this will not be specified.
core/src/main/java/com/github/dozermapper/core/builder/model/jaxb/FieldDefinition.java