public static TestExpression <Func <T1, T2, T3, T> > Lambda <T1, T2, T3, T>(Expression <Func <T1, T2, T3, TestExpression <T> > > expression)
        {
            /* In order to access the TestExpression value, the expression needs
             * to be evaluated and this requires that no unused parameters are
             * present at the evaluation time as this results in an error.
             * So to avoid this, the unused parameters are replaced with an default
             * value, then everything is evaluated, and the default value is
             * replaced back to a parameter
             */
            UnaryExpression constant1 = Expression.Convert(Expression.Constant(default(T1)), typeof(T1));
            UnaryExpression constant2 = Expression.Convert(Expression.Constant(default(T2)), typeof(T2));
            UnaryExpression constant3 = Expression.Convert(Expression.Constant(default(T3)), typeof(T3));

            ReplacerVisitor toReplacer1   = new ReplacerVisitor(expression.Parameters[0], constant1);
            ReplacerVisitor toReplacer2   = new ReplacerVisitor(expression.Parameters[1], constant2);
            ReplacerVisitor toReplacer3   = new ReplacerVisitor(expression.Parameters[2], constant3);
            ReplacerVisitor backReplacer1 = new ReplacerVisitor(constant1, expression.Parameters[0]);
            ReplacerVisitor backReplacer2 = new ReplacerVisitor(constant2, expression.Parameters[1]);
            ReplacerVisitor backReplacer3 = new ReplacerVisitor(constant3, expression.Parameters[2]);

            Expression body1 = toReplacer3.Visit(toReplacer2.Visit(toReplacer1.Visit(expression.Body)));
            Expression <Func <TestExpression <T> > > lambda1 = Expression.Lambda <Func <TestExpression <T> > >(body1);
            TestExpression <T> testExpression = lambda1.Compile().Invoke();

            Expression body2 = backReplacer3.Visit(backReplacer2.Visit(backReplacer1.Visit(testExpression.Expression)));
            Expression <Func <T1, T2, T3, T> > lambda2 = Expression.Lambda <Func <T1, T2, T3, T> >(body2, expression.Parameters[0], expression.Parameters[1], expression.Parameters[2]);

            return(new TestExpression <Func <T1, T2, T3, T> >(lambda2));
        }
        public static TestExpression Expr <T1, T2, T3, T4, T5>(TestExpression <T1> var1, TestExpression <T2> var2, TestExpression <T3> var3, TestExpression <T4> var4, TestExpression <T5> var5, Expression <Action <T1, T2, T3, T4, T5> > expression)
        {
            ParameterExpression parameter1 = expression.Parameters[0];
            ParameterExpression parameter2 = expression.Parameters[1];
            ParameterExpression parameter3 = expression.Parameters[2];
            ParameterExpression parameter4 = expression.Parameters[3];
            ParameterExpression parameter5 = expression.Parameters[4];

            ReplacerVisitor replacer1 = new ReplacerVisitor(parameter1, var1.Expression);
            ReplacerVisitor replacer2 = new ReplacerVisitor(parameter2, var2.Expression);
            ReplacerVisitor replacer3 = new ReplacerVisitor(parameter3, var3.Expression);
            ReplacerVisitor replacer4 = new ReplacerVisitor(parameter4, var4.Expression);
            ReplacerVisitor replacer5 = new ReplacerVisitor(parameter5, var5.Expression);

            Expression rewrittenExpression = replacer5.Visit(replacer4.Visit(replacer4.Visit(replacer3.Visit(replacer2.Visit(replacer1.Visit(expression.Body))))));

            return(new TestExpression(rewrittenExpression));
        }
        public static TestExpression Expr <T1>(TestExpression <T1> var, Expression <Action <T1> > expression)
        {
            ParameterExpression parameter = expression.Parameters[0];
            ReplacerVisitor     replacer  = new ReplacerVisitor(parameter, var.Expression);

            Expression rewrittenExpression = replacer.Visit(expression.Body);

            return(new TestExpression(rewrittenExpression));
        }
        public static TestExpression Expr <T1, T2>(TestExpression <T1> var1, TestExpression <T2> var2, Expression <Action <T1, T2> > expression)
        {
            ParameterExpression parameter1 = expression.Parameters[0];
            ParameterExpression parameter2 = expression.Parameters[1];

            ReplacerVisitor replacer1 = new ReplacerVisitor(parameter1, var1.Expression);
            ReplacerVisitor replacer2 = new ReplacerVisitor(parameter2, var2.Expression);

            Expression rewrittenExpression = replacer2.Visit(replacer1.Visit(expression.Body));

            return(new TestExpression(rewrittenExpression));
        }
        public static TestExpression <T> Expr <T1, T2, T3, T>(TestExpression <T1> var1, TestExpression <T2> var2, TestExpression <T3> var3, Expression <Func <T1, T2, T3, T> > expression)
        {
            ParameterExpression parameter1 = expression.Parameters[0];
            ParameterExpression parameter2 = expression.Parameters[1];
            ParameterExpression parameter3 = expression.Parameters[2];

            ReplacerVisitor replacer1 = new ReplacerVisitor(parameter1, var1.Expression);
            ReplacerVisitor replacer2 = new ReplacerVisitor(parameter2, var2.Expression);
            ReplacerVisitor replacer3 = new ReplacerVisitor(parameter3, var3.Expression);

            Expression rewrittenExpression = replacer3.Visit(replacer2.Visit(replacer1.Visit(expression.Body)));

            return(new TestExpression <T>(rewrittenExpression));
        }