public static Expression BindMethodExpression(MethodCallExpression m, bool allowPolymorphics)
        {
            if (m.Method.DeclaringType == typeof(ExpressionExtensions) && m.Method.Name == "Evaluate")
            {
                LambdaExpression lambda = (LambdaExpression)(ExpressionEvaluator.Eval(m.Arguments[0]));

                return(Expression.Invoke(lambda, m.Arguments.Skip(1).ToArray()));
            }

            if (m.Method.HasAttributeInherit <PolymorphicExpansionAttribute>() && !allowPolymorphics)
            {
                return(null);
            }

            MethodExpanderAttribute attribute = m.Method.GetCustomAttribute <MethodExpanderAttribute>();

            if (attribute != null)
            {
                if (attribute.ExpanderType.IsGenericTypeDefinition)
                {
                    if (!typeof(GenericMethodExpander).IsAssignableFrom(attribute.ExpanderType))
                    {
                        throw new InvalidOperationException("Expansion failed, '{0}' does not implement IMethodExpander or GenericMethodExpander".FormatWith(attribute.ExpanderType.TypeName()));
                    }

                    Expression[] args = m.Object == null?m.Arguments.ToArray() : m.Arguments.PreAnd(m.Object).ToArray();

                    var type = attribute.ExpanderType.MakeGenericType(m.Method.GetGenericArguments());
                    GenericMethodExpander expander = Activator.CreateInstance(type) as GenericMethodExpander;
                    return(Expression.Invoke(expander.GenericLambdaExpression, args));
                }
                else
                {
                    if (!typeof(IMethodExpander).IsAssignableFrom(attribute.ExpanderType))
                    {
                        throw new InvalidOperationException("Expansion failed, '{0}' does not implement IMethodExpander or GenericMethodExpander".FormatWith(attribute.ExpanderType.TypeName()));
                    }

                    IMethodExpander expander = (IMethodExpander)Activator.CreateInstance(attribute.ExpanderType);

                    Expression exp = expander.Expand(
                        m.Object,
                        m.Arguments.ToArray(),
                        m.Method);

                    return(exp);
                }
            }

            LambdaExpression lambdaExpression = GetFieldExpansion(m.Object?.Type, m.Method);

            if (lambdaExpression != null)
            {
                Expression[] args = m.Object == null?m.Arguments.ToArray() : m.Arguments.PreAnd(m.Object).ToArray();

                return(Expression.Invoke(lambdaExpression, args));
            }

            return(null);
        }
        static async Task <R> Bind <R>(CancellationToken cancellationToken, Expression <Func <R> > bind)
        {
            var mce = (MethodCallExpression)bind.Body;

            IQueryable query = (IQueryable)ExpressionEvaluator.Eval(mce.Arguments.FirstEx()) !;

            List <Expression> otherExpressions = mce.Arguments.Skip(1).Select(a => (Expression)ExpressionEvaluator.Eval(a) !).ToList();

            var mc2 = Expression.Call(mce.Method, otherExpressions.PreAnd(query.Expression));

            var provider = (IQueryProviderAsync)query.Provider;

            var value = await provider.ExecuteAsync(mc2, cancellationToken);

            return((R)value !);
        }