private static void AddDeclaredSourceTypeMappings(
            IEnumerable <DerivedTypePair> derivedTypePairs,
            IObjectMappingData declaredTypeMappingData,
            ICollection <DerivedTypeMapping> derivedTypeMappings,
            out bool declaredTypeHasUnconditionalTypePair)
        {
            var declaredTypeMapperData = declaredTypeMappingData.MapperData;

            foreach (var derivedTypePair in derivedTypePairs)
            {
                var condition = GetTypePairCondition(derivedTypePair, declaredTypeMapperData);

                var derivedTypeMapping = MappingFactory.GetDerivedTypeMapping(
                    declaredTypeMappingData,
                    declaredTypeMapperData.SourceObject,
                    derivedTypePair.DerivedTargetType);

                var returnMappingResult = Expression.Return(declaredTypeMapperData.ReturnLabelTarget, derivedTypeMapping);
                declaredTypeHasUnconditionalTypePair = (condition == null);

                if (declaredTypeHasUnconditionalTypePair)
                {
                    derivedTypeMappings.Add(DerivedTypeMapping.Unconditional(derivedTypePair, returnMappingResult));
                    return;
                }

                var ifConditionThenMap = Expression.IfThen(condition, returnMappingResult);

                derivedTypeMappings.Add(DerivedTypeMapping.Conditional(derivedTypePair, ifConditionThenMap));
            }

            declaredTypeHasUnconditionalTypePair = false;
        }
        private static void AddDerivedSourceTypeMappings(
            IEnumerable <Type> derivedSourceTypes,
            IObjectMappingData declaredTypeMappingData,
            ICollection <ParameterExpression> typedObjectVariables,
            ICollection <DerivedTypeMapping> derivedTypeMappings)
        {
            var declaredTypeMapperData = declaredTypeMappingData.MapperData;

            foreach (var derivedSourceType in derivedSourceTypes)
            {
                var typedVariableName       = "source" + derivedSourceType.GetVariableNameInPascalCase();
                var typedVariable           = Expression.Variable(derivedSourceType, typedVariableName);
                var typeAsConversion        = Expression.TypeAs(declaredTypeMapperData.SourceObject, derivedSourceType);
                var typedVariableAssignment = Expression.Assign(typedVariable, typeAsConversion);

                typedObjectVariables.Add(typedVariable);
                derivedTypeMappings.Add(typedVariableAssignment);

                var targetType = declaredTypeMapperData.TargetType.GetRuntimeTargetType(derivedSourceType);

                var condition = typedVariable.GetIsNotDefaultComparison();
                condition = AppendTargetValidCheckIfAppropriate(condition, targetType, declaredTypeMapperData);

                var        derivedTypePairs = GetTypePairsFor(derivedSourceType, targetType, declaredTypeMapperData);
                Expression typePairsCondition, ifSourceVariableIsDerivedTypeThenMap;

                if (derivedTypePairs.None())
                {
                    ifSourceVariableIsDerivedTypeThenMap = GetIfConditionThenMapExpression(
                        declaredTypeMappingData,
                        condition,
                        typedVariable,
                        targetType);

                    derivedTypeMappings.Add(DerivedTypeMapping
                                            .Conditional(derivedSourceType, ifSourceVariableIsDerivedTypeThenMap));
                    continue;
                }

                var derivedTargetType = derivedTypePairs[0].DerivedTargetType;

                if (derivedTypePairs.All(tp => !tp.HasConfiguredCondition))
                {
                    typePairsCondition = GetTargetValidCheckOrNull(derivedTargetType, declaredTypeMapperData);

                    if (typePairsCondition == null)
                    {
                        ifSourceVariableIsDerivedTypeThenMap = GetIfConditionThenMapExpression(
                            declaredTypeMappingData,
                            condition,
                            typedVariable,
                            derivedTargetType);

                        derivedTypeMappings.Add(DerivedTypeMapping
                                                .Conditional(derivedSourceType, ifSourceVariableIsDerivedTypeThenMap));
                        continue;
                    }

                    ifSourceVariableIsDerivedTypeThenMap = GetMapFromConditionOrDefaultExpression(
                        declaredTypeMappingData,
                        condition,
                        typePairsCondition,
                        typedVariable,
                        targetType,
                        derivedTargetType);

                    derivedTypeMappings.Add(DerivedTypeMapping
                                            .Conditional(derivedSourceType, ifSourceVariableIsDerivedTypeThenMap));
                    continue;
                }

                typePairsCondition = GetTypePairsCondition(derivedTypePairs, declaredTypeMapperData);

                ifSourceVariableIsDerivedTypeThenMap = GetMapFromConditionOrDefaultExpression(
                    declaredTypeMappingData,
                    condition,
                    typePairsCondition,
                    typedVariable,
                    targetType,
                    derivedTargetType);

                derivedTypeMappings.Add(DerivedTypeMapping
                                        .Conditional(derivedSourceType, ifSourceVariableIsDerivedTypeThenMap));
            }
        }