public void ChangeBinaryToMethodCall()
        {
            var addresses = Expression.MakeMemberAccess(
                Expression.Parameter(typeof(Person), "person"),
                typeof(Person).GetProperty(nameof(Person.Addresses)));

            var count = Expression.MakeMemberAccess(addresses, typeof(Address).GetProperty("Count"));

            // person.PersonId == "1"
            BinaryExpression personIdEqualsOne =
                Expression.MakeBinary(
                    ExpressionType.Equal,
                    Expression.MakeMemberAccess(
                        Expression.Parameter(typeof(Person), "person"),
                        typeof(Person).GetProperty(nameof(Person.PersonId))),
                    Expression.Constant("1"));


            // person.PersonId
            Expression personId = personIdEqualsOne.Left;

            // person.Addresses
            MemberExpression personAddresses = new ChangeMemberProperty(
                typeof(Person),
                personId,
                nameof(Person.Addresses))
                                               .Change();

            // Select method
            MethodInfo selectMethod = EnumerableMethodInfo.Select <Address, int>();

            // address
            ParameterExpression addressParam = Expression.Parameter(typeof(Address), "address");

            // address.AddressId
            MemberExpression memberAccess = Expression.MakeMemberAccess(
                addressParam,
                typeof(Address).GetProperty(nameof(Address.AddressId)));

            // address => address.AddressId
            LambdaExpression lambda = Expression.Lambda(
                memberAccess,
                addressParam
                );

            // person.Addresses.Select(address => address.AddressId)
            MethodCallExpression selectAddresses = Expression.Call(selectMethod, new List <Expression> {
                personAddresses, lambda
            });

            Assert.NotNull(selectAddresses);
        }
        public void ChangeMemberAccess()
        {
            MemberExpression personId = Expression.MakeMemberAccess(
                Expression.Parameter(typeof(Person)),
                typeof(Person).GetProperty(nameof(Person.PersonId)));

            Expression personLastName = new ChangeMemberProperty(typeof(Person),
                                                                 personId,
                                                                 nameof(Person.LastName))
                                        .Change();

            Assert.IsAssignableFrom <MemberExpression>(personLastName);
            Assert.Equal(nameof(Person.LastName), ((MemberExpression)personLastName).Member.Name);
        }
        public void ChangeNestedMemberAccess()
        {
            MemberExpression personId = Expression.MakeMemberAccess(
                Expression.Parameter(typeof(Person)),
                typeof(Person).GetProperty(nameof(Person.PersonId)));

            MemberExpression personAddresses = new ChangeMemberProperty(
                typeof(Person),
                personId,
                nameof(Person.Addresses))
                                               .Change();

            // todo: fix to work with collection property accessors
            MemberExpression newMember = Expression.MakeMemberAccess(
                personAddresses,
                personAddresses.Type.GetProperty(nameof(Address.AddressId)));

            Assert.IsAssignableFrom <MemberExpression>(newMember);
            Assert.Equal(nameof(Address.AddressId), newMember.Member.Name);
        }