protected void writeDeepDestinationValue(Object destObj, Object destFieldValue, FieldMap fieldMap) {
        // follow deep field hierarchy. If any values are null along the way, then create a new instance
        DeepHierarchyElement[] hierarchy = getDeepFieldHierarchy(destObj, fieldMap.getDestDeepIndexHintContainer());
        // first, iteratate through hierarchy and instantiate any objects that are null
        Object parentObj = destObj;
        int hierarchyLength = hierarchy.length - 1;
        int hintIndex = 0;
        for (int i = 0; i < hierarchyLength; i++) {
            DeepHierarchyElement hierarchyElement = hierarchy[i];
            PropertyDescriptor pd = hierarchyElement.getPropDescriptor();
            Object value = ReflectionUtils.invoke(pd.getReadMethod(), parentObj, null);
            Class<?> clazz;
            Class<?> collectionEntryType;
            if (value == null) {
                clazz = pd.getPropertyType();
                if (clazz.isInterface() && (i + 1) == hierarchyLength && fieldMap.getDestHintContainer() != null) {
                    // before setting the property on the destination object we should check for a destination hint. need to know
                    // that we are at the end of the line determine the property type
                    clazz = fieldMap.getDestHintContainer().getHint();
                }
                Object o = null;
                if (clazz.isArray()) {
                    o = MappingUtils.prepareIndexedCollection(clazz, null, destBeanCreator.create(clazz.getComponentType()),
                                                              hierarchyElement.getIndex());
                } else if (Collection.class.isAssignableFrom(clazz)) {

                    Class<?> genericType = ReflectionUtils.determineGenericsType(parentObj.getClass(), pd);
                    if (genericType != null) {
                        collectionEntryType = genericType;
                    } else {
                        collectionEntryType = fieldMap.getDestDeepIndexHintContainer().getHint(hintIndex);
                        //hint index is used to handle multiple hints
                        hintIndex += 1;
                    }

                    o = MappingUtils.prepareIndexedCollection(clazz, null, destBeanCreator.create(collectionEntryType), hierarchyElement
                            .getIndex());
                } else {
                    try {
                        o = destBeanCreator.create(clazz);
                    } catch (Exception e) {
                        //lets see if they have a factory we can try as a last ditch. If not...throw the exception:
                        if (fieldMap.getClassMap().getDestClassBeanFactory() != null) {
                            o = destBeanCreator.create(new BeanCreationDirective(null, fieldMap.getClassMap().getSrcClassToMap(), clazz, clazz, fieldMap.getClassMap()
                                    .getDestClassBeanFactory(), fieldMap.getClassMap().getDestClassBeanFactoryId(), null, null));
                        } else {
                            MappingUtils.throwMappingException(e);
                        }
                    }
                }

                ReflectionUtils.invoke(pd.getWriteMethod(), parentObj, new Object[] {o});
                value = ReflectionUtils.invoke(pd.getReadMethod(), parentObj, null);
            }

            //Check to see if collection needs to be resized
            if (MappingUtils.isSupportedCollection(value.getClass())) {
                int currentSize = CollectionUtils.getLengthOfCollection(value);
                if (currentSize < hierarchyElement.getIndex() + 1) {
                    collectionEntryType = pd.getPropertyType().getComponentType();

                    if (collectionEntryType == null) {
                        collectionEntryType = ReflectionUtils.determineGenericsType(parentObj.getClass(), pd);

                        // if the target list is a List that doesn't have type specified, we can
                        // try to use the deep-index-hint.  If the list has more than 1 element, there is no
                        // way to tell which class to use, so we'll just try the first one.
                        if (collectionEntryType == null) {
                            if (log.isWarnEnabled()) {
                                log.warn(fieldName + " is in a Collection with an unspecified type.");
                            }
                            if (destDeepIndexHintContainer != null && destDeepIndexHintContainer.getHints() != null
                                && destDeepIndexHintContainer.getHints().size() > 0) {
                                collectionEntryType = destDeepIndexHintContainer.getHints().get(0);
                                if (log.isWarnEnabled()) {
                                    log.warn("Using deep-index-hint to predict containing Collection type for field "
                                             + fieldName + " to be " + collectionEntryType);
                                }
                            }
                        }
                    }

                    value = MappingUtils.prepareIndexedCollection(pd.getPropertyType(), value, destBeanCreator.create(collectionEntryType), hierarchyElement.getIndex());
                    //value = MappingUtils.prepareIndexedCollection(pd.getPropertyType(), value, DestBeanCreator.create(collectionEntryType), hierarchyElement.getIndex());
                    ReflectionUtils.invoke(pd.getWriteMethod(), parentObj, new Object[] {value});
                }
            }

            if (value != null && value.getClass().isArray()) {
                parentObj = Array.get(value, hierarchyElement.getIndex());
            } else if (value != null && Collection.class.isAssignableFrom(value.getClass())) {
                parentObj = MappingUtils.getIndexedValue(value, hierarchyElement.getIndex());
            } else {
                parentObj = value;
            }
        }
        // second, set the very last field in the deep hierarchy
        PropertyDescriptor pd = hierarchy[hierarchy.length - 1].getPropDescriptor();

        Class<?> type;
        // For one-way mappings there could be no read method
        if (pd.getReadMethod() != null) {
            type = pd.getReadMethod().getReturnType();
        } else {
            type = pd.getWriteMethod().getParameterTypes()[0];
        }

        if (!type.isPrimitive() || destFieldValue != null) {
            if (!isIndexed) {
                Method method = null;
                if (!isCustomSetMethod()) {
                    method = pd.getWriteMethod();
                } else {
                    try {
                        method = ReflectionUtils.findAMethod(parentObj.getClass(), getSetMethodName(), beanContainer);
                    } catch (NoSuchMethodException e) {
                        MappingUtils.throwMappingException(e);
                    }
                }

                ReflectionUtils.invoke(method, parentObj, new Object[] {destFieldValue});
            } else {
                writeIndexedValue(parentObj, destFieldValue);
            }
        }
    }
Internal class used to read and write values for fields that have a getter and setter method. This class encapsulates
underlying dozer specific logic such as index mapping and deep mapping for reading and writing field values. Only
intended for internal use.
core/src/main/java/com/github/dozermapper/core/propertydescriptor/GetterSetterPropertyDescriptor.java