GetAssignmentFromBinding(MemberBinding binding,
                                 ParameterExpression paramSourceExisting,
                                 ParameterExpression paramSourceNew,
                                 ParameterExpression paramDestination)
        {
            var existingAssignment = binding as MemberAssignment
                                     ?? throw new ArgumentException("Only binding of type MemberAssignment can be used. " +
                                                                    $"Received binding of type {binding.BindingType}, {binding.ToString()}");

            var targetMember = Expression.MakeMemberAccess(paramDestination, existingAssignment.Member);

            var newExpression = new ParameterReplacerVisitor(paramSourceExisting, paramSourceNew)
                                .Visit(existingAssignment.Expression);

            var assignment = Expression.Assign(targetMember, newExpression);

            return(assignment);
        }
        public Expression <Func <TSource, TDestination> > CombineIntoMapperWithConstructor(
            Expression <Func <TSource, TDestination> > recipientExpression,
            Expression <Func <TSource, TDestination> > donorExpression)
        {
            var paramReplacer = new ParameterReplacerVisitor(
                donorExpression.Parameters[0],
                recipientExpression.Parameters[0]);

            var donorWithCorrectedParam = (Expression <Func <TSource, TDestination> >)paramReplacer.Visit(donorExpression);

            var visitor = new MemberInitBindingsCombinationVisitor <TSource, TDestination>()
            {
                recipientExpression = recipientExpression,
                donorExpression     = donorWithCorrectedParam
            };

            var combinedExpr = (Expression <Func <TSource, TDestination> >)visitor.Visit(recipientExpression);

            return(combinedExpr);
        }