/// <summary>
        /// Translates an OData $filter represented by <see cref="FilterClause"/> to <see cref="Expression"/> and apply to <see cref="IQueryable" />.
        /// </summary>
        /// <param name="binder">The given filter binder.</param>
        /// <param name="query">The given queryable.</param>
        /// <param name="filterClause">The filter clause.</param>
        /// <param name="context">The query binder context.</param>
        /// <returns>The applied result.</returns>
        public static IQueryable ApplyBind(this IFilterBinder binder, IQueryable query, FilterClause filterClause, QueryBinderContext context)
        {
            if (binder == null)
            {
                throw Error.ArgumentNull(nameof(binder));
            }

            if (query == null)
            {
                throw Error.ArgumentNull(nameof(query));
            }

            if (filterClause == null)
            {
                throw Error.ArgumentNull(nameof(filterClause));
            }

            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            Expression filterExp = binder.BindFilter(filterClause, context);

            return(ExpressionHelpers.Where(query, filterExp, context.ElementClrType));
        }
        /// <summary>
        /// Translates an OData $filter represented by <see cref="FilterClause"/> to <see cref="Expression"/> and apply to <see cref="Expression" />.
        /// </summary>
        /// <param name="binder">The given filter binder.</param>
        /// <param name="source">The given source.</param>
        /// <param name="filterClause">The filter clause.</param>
        /// <param name="context">The query binder context.</param>
        /// <returns>The applied result.</returns>
        public static Expression ApplyBind(this IFilterBinder binder, Expression source, FilterClause filterClause, QueryBinderContext context)
        {
            if (binder == null)
            {
                throw Error.ArgumentNull(nameof(binder));
            }

            if (source == null)
            {
                throw Error.ArgumentNull(nameof(source));
            }

            if (filterClause == null)
            {
                throw Error.ArgumentNull(nameof(filterClause));
            }

            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            Expression filterExp = binder.BindFilter(filterClause, context);

            Type elementType = context.ElementClrType;

            MethodInfo filterMethod;

            if (typeof(IQueryable).IsAssignableFrom(source.Type))
            {
                filterMethod = ExpressionHelperMethods.QueryableWhereGeneric.MakeGenericMethod(elementType);
            }
            else
            {
                filterMethod = ExpressionHelperMethods.EnumerableWhereGeneric.MakeGenericMethod(elementType);
            }

            return(Expression.Call(filterMethod, source, filterExp));
        }
        /// <summary>
        /// Translates an OData $filter represented by <see cref="FilterClause"/> to <see cref="Expression"/> and apply to <see cref="IEnumerable" />.
        /// </summary>
        /// <param name="binder">The given filter binder.</param>
        /// <param name="query">The given IEnumerable.</param>
        /// <param name="filterClause">The filter clause.</param>
        /// <param name="context">The query binder context.</param>
        /// <returns>The applied result.</returns>
        public static IEnumerable ApplyBind(this IFilterBinder binder, IEnumerable query, FilterClause filterClause, QueryBinderContext context)
        {
            if (binder == null)
            {
                throw Error.ArgumentNull(nameof(binder));
            }

            if (query == null)
            {
                throw Error.ArgumentNull(nameof(query));
            }

            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            Expression filterExp = binder.BindFilter(filterClause, context);

            MethodInfo whereMethod = ExpressionHelperMethods.EnumerableWhereGeneric.MakeGenericMethod(context.ElementClrType);

            return(whereMethod.Invoke(null, new object[] { query, filterExp }) as IEnumerable);
        }