private static void MapProperties(PropertyMapInfo propMapInfo, IMapperConfiguration mapperConfiguration)
        {
            var sourceType              = propMapInfo.SourceType;
            var sourceProperty          = propMapInfo.SourcePropertyInfos;
            var destinationType         = propMapInfo.DestinationType;
            var destinationPropertyInfo = propMapInfo.DestinationPropertyInfo;

            var createMapMethod = mapperConfiguration == null?GenericCreateMapStaticApi.MakeGenericMethod(sourceType, destinationType) : GenericCreateMap.MakeGenericMethod(sourceType, destinationType);

            var mapObject           = createMapMethod.Invoke(mapperConfiguration ?? null, new object[] {});
            var mapObjectExpression = Expression.Constant(mapObject);

            var sourceParameter      = Expression.Parameter(sourceType);
            var destinationParameter = Expression.Parameter(destinationType);

            var destinationMember = Expression.Lambda(
                Expression.Convert(
                    Expression.Property(destinationParameter, destinationPropertyInfo),
                    typeof(object)
                    ),
                destinationParameter
                );

            var memberConfigType          = typeof(IMemberConfigurationExpression <>).MakeGenericType(sourceType);
            var memberConfigTypeParameter = Expression.Parameter(memberConfigType);

            var finalPropertyType  = sourceProperty.Last().PropertyType;
            var propertyExpression = sourceProperty.Aggregate <PropertyInfo, Expression>(null, (current, prop) => current == null ? Expression.Property(sourceParameter, prop) : Expression.Property(current, prop));

            var memberOptions = Expression.Call(memberConfigTypeParameter,
                                                nameof(IMemberConfigurationExpression <object> .MapFrom),
                                                new Type[] { finalPropertyType },
                                                Expression.Lambda(
                                                    propertyExpression,
                                                    sourceParameter
                                                    ));

            var forMemberMethod = Expression.Call(mapObjectExpression,
                                                  nameof(IMappingExpression.ForMember),
                                                  Type.EmptyTypes,
                                                  destinationMember,
                                                  Expression.Lambda(memberOptions, memberConfigTypeParameter));

            Expression.Lambda(forMemberMethod).Compile().DynamicInvoke();
        }
        private static MethodCallExpression GetMapFromCall(ParameterExpression memberConfigTypeParameter, PropertyInfo targetPropertyInfo, PropertyMapInfo propMapInfo, ParameterExpression sourceTypeParameter)
        {
            var sourcePropertyInfos = propMapInfo.SourcePropertyInfos;
            var targetPropertyName  = targetPropertyInfo.Name;

            Debug.WriteLine(
                $"-- Mapping property {string.Join(".", sourcePropertyInfos.Select(s => s.Name))} to target type {targetPropertyName}");

            var finalSourcePropertyType = sourcePropertyInfos.Last().PropertyType;
            var propertyExpression      =
                sourcePropertyInfos.Aggregate <PropertyInfo, Expression>(null, (current, prop) => current == null
                    ? Expression.Property(sourceTypeParameter, prop)
                    : Expression.Property(current, prop));

            return(Expression.Call(memberConfigTypeParameter, nameof(IMemberConfigurationExpression.MapFrom),
                                   new Type[] { finalSourcePropertyType },
                                   Expression.Lambda(
                                       propertyExpression,
                                       sourceTypeParameter
                                       )));
        }