private static Func <IObjectMappingDataFactoryBridge, TSource, TTarget, int?, object, object, object, object, object> GetPartialTrustMappingDataCreator <TSource, TTarget>(
            MappingTypes mappingTypes)
        {
            var createCallerKey = DeclaredAndRuntimeTypesKey.For <TSource, TTarget>(mappingTypes);

            var createCallerFunc = GlobalContext.Instance.Cache.GetOrAdd(createCallerKey, k =>
            {
                var bridgeParameter         = Expression.Parameter(typeof(IObjectMappingDataFactoryBridge), "bridge");
                var sourceParameter         = Parameters.Create(k.DeclaredSourceType, "source");
                var targetParameter         = Parameters.Create(k.DeclaredTargetType, "target");
                var elementIndexParameter   = Expression.Parameter(typeof(int?), "i");
                var elementKeyParameter     = Expression.Parameter(typeof(object), "key");
                var mappingTypesParameter   = Expression.Parameter(typeof(object), "mappingTypes");
                var mappingContextParameter = Expression.Parameter(typeof(object), "mappingContext");
                var parentParameter         = Expression.Parameter(typeof(object), "parent");

                var createMethod = bridgeParameter.Type
                                   .GetPublicInstanceMethod("CreateMappingData")
                                   .MakeGenericMethod(
                    k.DeclaredSourceType,
                    k.DeclaredTargetType,
                    k.RuntimeSourceType,
                    k.RuntimeTargetType);

                var createCall = Expression.Call(
                    bridgeParameter,
                    createMethod,
                    sourceParameter,
                    targetParameter,
                    elementIndexParameter,
                    elementKeyParameter,
                    mappingTypesParameter,
                    mappingContextParameter,
                    parentParameter);

                var createLambda = Expression
                                   .Lambda <Func <IObjectMappingDataFactoryBridge, TSource, TTarget, int?, object, object, object, object, object> >(
                    createCall,
                    bridgeParameter,
                    sourceParameter,
                    targetParameter,
                    elementIndexParameter,
                    elementKeyParameter,
                    mappingTypesParameter,
                    mappingContextParameter,
                    parentParameter);

                return(createLambda.Compile());
            });

            return(createCallerFunc);
        }
        private static MappingDataCreator <TSource, TTarget> GetMappingDataCreator <TSource, TTarget>(
            MappingTypes mappingTypes)
        {
            var constructorKey = DeclaredAndRuntimeTypesKey.For <TSource, TTarget>(mappingTypes);

            var constructionFunc = GlobalContext.Instance.Cache.GetOrAdd(constructorKey, k =>
            {
                var elementIndexParameter   = Expression.Parameter(typeof(int?), "i");
                var elementKeyParameter     = Expression.Parameter(typeof(object), "key");
                var mappingTypesParameter   = typeof(MappingTypes).GetOrCreateParameter("mappingTypes");
                var mappingContextParameter = typeof(IMappingContext).GetOrCreateParameter("mappingContext");
                var mappingDataParameter    = typeof(IObjectMappingData).GetOrCreateParameter("mappingData");

                var dataType = typeof(ObjectMappingData <,>)
                               .MakeGenericType(k.RuntimeSourceType, k.RuntimeTargetType);

                var sourceParameter = Parameters.Create(k.DeclaredSourceType, "source");
                var targetParameter = Parameters.Create(k.DeclaredTargetType, "target");

                var targetParameterValue = TypeExtensionsPolyfill.IsValueType(k.RuntimeTargetType) && k.DeclaredTargetType.CanBeNull()
                    ? Expression.Coalesce(targetParameter, k.RuntimeTargetType.ToDefaultExpression())
                    : (Expression)targetParameter;

                var constructorCall = Expression.New(
                    dataType.GetPublicInstanceConstructors().First(),
                    sourceParameter.GetConversionTo(k.RuntimeSourceType),
                    targetParameterValue.GetConversionTo(k.RuntimeTargetType),
                    elementIndexParameter,
                    elementKeyParameter,
                    mappingTypesParameter,
                    mappingContextParameter,
                    mappingDataParameter,
                    true.ToConstantExpression()); // <- createMapper

                var constructionLambda = Expression.Lambda <MappingDataCreator <TSource, TTarget> >(
                    constructorCall,
                    sourceParameter,
                    targetParameter,
                    elementIndexParameter,
                    elementKeyParameter,
                    mappingTypesParameter,
                    mappingContextParameter,
                    mappingDataParameter);

                return(constructionLambda.Compile());
            });

            return(constructionFunc);
        }
        private static MappingDataCreator <TSource, TTarget> GetMappingDataCreator <TSource, TTarget>(
            MappingTypes mappingTypes)
        {
            var constructorKey = DeclaredAndRuntimeTypesKey.For <TSource, TTarget>(mappingTypes);

            // TODO: Local cache
            var constructionFunc = GlobalContext.Instance.Cache.GetOrAdd(constructorKey, k =>
            {
                var mapperKeyParameter       = Expression.Parameter(typeof(ObjectMapperKeyBase), "mapperKey");
                var enumerableIndexParameter = Expression.Parameter(typeof(int?), "i");

                var dataType = typeof(ObjectMappingData <,>)
                               .MakeGenericType(k.RuntimeSourceType, k.RuntimeTargetType);

                var sourceParameter = Parameters.Create(k.DeclaredSourceType, "source");
                var targetParameter = Parameters.Create(k.DeclaredTargetType, "target");

                var constructorCall = Expression.New(
                    dataType.GetPublicInstanceConstructors().First(),
                    sourceParameter.GetConversionTo(k.RuntimeSourceType),
                    targetParameter.GetConversionTo(k.RuntimeTargetType),
                    enumerableIndexParameter,
                    mapperKeyParameter,
                    Parameters.MappingContext,
                    Parameters.ObjectMappingData);

                var constructionLambda = Expression.Lambda <MappingDataCreator <TSource, TTarget> >(
                    constructorCall,
                    sourceParameter,
                    targetParameter,
                    enumerableIndexParameter,
                    mapperKeyParameter,
                    Parameters.MappingContext,
                    Parameters.ObjectMappingData);

                return(constructionLambda.Compile());
            });

            return(constructionFunc);
        }