private static ICollection <IncompleteMappingData> GetIncompleteMappingPlanData(
     IEnumerable <ObjectMapperData> mapperDatas)
 {
     return(mapperDatas
            .Project(md => new
     {
         MapperData = md,
         IsUnconstructable = TargetIsUnconstructable(md),
         UnmappedMembers = md
                           .DataSourcesByTargetMember
                           .Filter(pair => !pair.Value.HasValue)
                           .ToArray(),
         UnpairedEnums = EnumMappingMismatchFinder.FindMismatches(md)
     })
            .Filter(d => d.IsUnconstructable || d.UnmappedMembers.Any() || d.UnpairedEnums.Any())
            .GroupBy(d => d.MapperData.GetRootMapperData())
            .Project(g => new IncompleteMappingData
     {
         RootMapperData = g.Key,
         UnconstructableTargetTypes = g
                                      .Filter(d => d.IsUnconstructable)
                                      .Project(d => d.MapperData)
                                      .ToArray(),
         UnmappedMembers = g
                           .SelectMany(d => d.UnmappedMembers)
                           .ToDictionary(kvp => kvp.Key, kvp => kvp.Value),
         UnpairedEnums = g
                         .SelectMany(d => d.UnpairedEnums)
                         .ToArray()
     })
            .ToArray());
 }
        public static Expression Process(Expression lambda, ObjectMapperData mapperData)
        {
            var targetMemberDatas = GetAllTargetMemberDatas(mapperData);

            if (targetMemberDatas.None())
            {
                return(lambda);
            }

            var finder = new EnumMappingMismatchFinder(mapperData, targetMemberDatas);

            finder.Visit(lambda);

            var assignmentReplacements = finder._assignmentsByMismatchSet
                                         .SelectMany(kvp => kvp.Value.Project(assignment => new
            {
                Assignment            = assignment,
                AssignmentWithWarning = (Expression)Expression.Block(kvp.Key.Warnings, assignment)
            }))
                                         .ToDictionary(d => d.Assignment, d => d.AssignmentWithWarning);

            var updatedLambda = lambda.Replace(assignmentReplacements);

            return(updatedLambda);
        }