private InvocationExpander(ParameterExpression parameter, Expression expansion, InvocationExpander previous)
            {
                EnitityUtility.CheckArgumentNotNull(parameter, "parameter");
                EnitityUtility.CheckArgumentNotNull(expansion, "expansion");
                EnitityUtility.CheckArgumentNotNull(previous, "previous");

                _parameter = parameter;
                _expansion = expansion;
                _previous  = previous;
            }
            protected override Expression VisitParameter(ParameterExpression p)
            {
                InvocationExpander expander = this;

                while (null != expander)
                {
                    if (expander._parameter == p)
                    {
                        return(base.Visit(expander._expansion));
                    }
                    expander = expander._previous;
                }
                return(base.VisitParameter(p));
            }
        public void CanExpandTwoVariablePredicate()
        {
            Expression <Func <int, int, bool> > p1 = (x, y) => x > y;
            Expression <Func <int, int, bool> > p2 = (y, x) => x > y;

            // (x, y) => x > y || invoke((y, x) => x > y, x, y);
            p1 = Expression.Lambda <Func <int, int, bool> >(Expression.OrElse(p1.Body, Expression.Invoke(p2, p1.Parameters.ToArray())), p1.Parameters.ToArray());
            p1.Nodes().OfType <ParameterExpression>().Count().Should().Be(10);
            p1.Nodes().OfType <InvocationExpression>().Count().Should().Be(1);

            // (x, y) => x > y || y > x;
            p1 = InvocationExpander.Expand(p1);
            p1.Nodes().OfType <ParameterExpression>().Count().Should().Be(6);
            p1.Nodes().OfType <InvocationExpression>().Count().Should().Be(0);

            //expected result
            Expression <Func <int, int, bool> > pExp = (x, y) => x > y || y > x;

            p1.ToString().Should().Be(pExp.ToString());
        }
        public void CanExpandSimplePredicate()
        {
            Expression <Predicate <int> > p1 = x => x > 2;
            Expression <Predicate <int> > p2 = y => y < 3;

            // x => x > 2 && invoke(y => y < 3, x);
            p1 = Expression.Lambda <Predicate <int> >(Expression.AndAlso(p1.Body, Expression.Invoke(p2, p1.Parameters.ToArray())), p1.Parameters.ToArray());
            p1.Nodes().OfType <ParameterExpression>().Count().Should().Be(5);
            p1.Nodes().OfType <InvocationExpression>().Count().Should().Be(1);

            // x => x > 2 && x < 3
            p1 = InvocationExpander.Expand(p1);
            p1.Nodes().OfType <ParameterExpression>().Count().Should().Be(3);
            p1.Nodes().OfType <InvocationExpression>().Count().Should().Be(0);

            //expected result
            Expression <Predicate <int> > pExp = x => x > 2 && x < 3;

            p1.ToString().Should().Be(pExp.ToString());
        }
 public static Expression <Func <T, bool> > ExpandInvocations <T>(this Expression <Func <T, bool> > expr)
 {
     return(InvocationExpander.Expand(expr));
 }
 /// <summary>
 /// Expands all InvocationExpression instances within the given expression.
 /// </summary>
 /// <param name="expression">Expression to expand.</param>
 /// <returns>Expanded expression.</returns>
 public static Expression ExpandInvocations(this Expression expression)
 {
     return(InvocationExpander.Expand(expression));
 }