public static bool IsHijackable(ODataQueryOptions <V2FeedPackage> options, out HijackableQueryParameters hijackable)
        {
            // Check if we can process the filter clause
            if (!CanProcessFilterClause(options))
            {
                hijackable = null;
                return(false);
            }

            // Build expression (this works around all internal classes in the OData library - all we want is an expression tree)
            var expression = options.ApplyTo(EmptyQueryable, QueryResultDefaults.DefaultQuerySettings).Expression;

            // Unravel the comparisons into a list we can reason about
            List <Tuple <Target, string> > comparisons = new List <Tuple <Target, string> >();
            Expression remnant = FindQueryableWhere(expression as MethodCallExpression);

            MethodCallExpression where;
            while (IsQueryableWhere(where = remnant as MethodCallExpression))
            {
                var extractedComparisons = ExtractComparison(where).ToList();
                if (!extractedComparisons.Any() || extractedComparisons.Any(c => c == null))
                {
                    hijackable = null;
                    return(false);
                }
                else
                {
                    // We recognize this comparison, record it and keep iterating on the nested expression
                    comparisons.AddRange(extractedComparisons);
                    remnant = where.Arguments[0];
                }
            }

            // We should be able to hijack here
            if (comparisons.Any())
            {
                hijackable = new HijackableQueryParameters();
                foreach (var comparison in comparisons)
                {
                    if (comparison.Item1 == Target.Id)
                    {
                        hijackable.Id = comparison.Item2;
                    }
                    else if (comparison.Item1 == Target.Version)
                    {
                        hijackable.Version = comparison.Item2;
                    }
                    else
                    {
                        hijackable = null;
                        return(false);
                    }
                }

                return(true);
            }

            hijackable = null;
            return(false);
        }
        public static bool IsHijackable(ODataQueryOptions<V2FeedPackage> options, out HijackableQueryParameters hijackable)
        {
            // Check if we can process the filter clause
            if (!CanProcessFilterClause(options))
            {
                hijackable = null;
                return false;
            }

            // Build expression (this works around all internal classes in the OData library - all we want is an expression tree)
            var expression = options.ApplyTo(EmptyQueryable, QueryResultDefaults.DefaultQuerySettings).Expression;

            // Unravel the comparisons into a list we can reason about
            List<Tuple<Target, string>> comparisons = new List<Tuple<Target, string>>();
            Expression remnant = FindQueryableWhere(expression as MethodCallExpression);
            MethodCallExpression where;
            while (IsQueryableWhere(where = remnant as MethodCallExpression))
            {
                var extractedComparisons = ExtractComparison(where).ToList();
                if (!extractedComparisons.Any() || extractedComparisons.Any(c => c == null))
                {
                    hijackable = null;
                    return false;
                }
                else
                {
                    // We recognize this comparison, record it and keep iterating on the nested expression
                    comparisons.AddRange(extractedComparisons);
                    remnant = where.Arguments[0];
                }
            }

            // We should be able to hijack here
            if (comparisons.Any())
            {
                hijackable = new HijackableQueryParameters();
                foreach (var comparison in comparisons)
                {
                    if (comparison.Item1 == Target.Id)
                    {
                        hijackable.Id = comparison.Item2;
                    }
                    else if (comparison.Item1 == Target.Version)
                    {
                        hijackable.Version = comparison.Item2;
                    }
                    else
                    {
                        hijackable = null;
                        return false;
                    }
                }

                return true;
            }

            hijackable = null;
            return false;
        }
        public static bool IsHijackable(ODataQueryOptions <V2FeedPackage> options, out HijackableQueryParameters hijackable)
        {
            if (options.Filter?.FilterClause != null &&
                options.Filter.FilterClause.Expression.Kind == QueryNodeKind.SingleValueFunctionCall &&
                options.Filter.FilterClause.ItemType.Definition.TypeKind == EdmTypeKind.Entity)
            {
                var functionCallExpression = (SingleValueFunctionCallNode)options.Filter.FilterClause.Expression;
                if (string.Equals(functionCallExpression.Name, "substringof", StringComparison.OrdinalIgnoreCase))
                {
                    // The 'substringof' function cannot be applied to an enumeration-typed argument
                    hijackable = null;
                    return(false);
                }
            }

            // Build expression (this works around all internal classes in the OData library - all we want is an expression tree)
            var expression = options.ApplyTo(EmptyQueryable, QueryResultDefaults.DefaultQuerySettings).Expression;

            // Unravel the comparisons into a list we can reason about
            List <Tuple <Target, string> > comparisons = new List <Tuple <Target, string> >();
            Expression remnant = FindQueryableWhere(expression as MethodCallExpression);

            MethodCallExpression where;
            while (IsQueryableWhere(where = remnant as MethodCallExpression))
            {
                var extractedComparisons = ExtractComparison(where).ToList();
                if (!extractedComparisons.Any() || extractedComparisons.Any(c => c == null))
                {
                    hijackable = null;
                    return(false);
                }
                else
                {
                    // We recognize this comparison, record it and keep iterating on the nested expression
                    comparisons.AddRange(extractedComparisons);
                    remnant = where.Arguments[0];
                }
            }

            // We should be able to hijack here
            if (comparisons.Any())
            {
                hijackable = new HijackableQueryParameters();
                foreach (var comparison in comparisons)
                {
                    if (comparison.Item1 == Target.Id)
                    {
                        hijackable.Id = comparison.Item2;
                    }
                    else if (comparison.Item1 == Target.Version)
                    {
                        hijackable.Version = comparison.Item2;
                    }
                    else
                    {
                        hijackable = null;
                        return(false);
                    }
                }

                return(true);
            }

            hijackable = null;
            return(false);
        }
        public static bool IsHijackable(ODataQueryOptions<V2FeedPackage> options, out HijackableQueryParameters hijackable)
        {
            if (options.Filter?.FilterClause != null
                && options.Filter.FilterClause.Expression.Kind == QueryNodeKind.SingleValueFunctionCall
                && options.Filter.FilterClause.ItemType.Definition.TypeKind == EdmTypeKind.Entity)
            {
                var functionCallExpression = (SingleValueFunctionCallNode) options.Filter.FilterClause.Expression;
                if (string.Equals(functionCallExpression.Name, "substringof", StringComparison.OrdinalIgnoreCase))
                {
                    // The 'substringof' function cannot be applied to an enumeration-typed argument
                    hijackable = null;
                    return false;
                }
            }

            // Build expression (this works around all internal classes in the OData library - all we want is an expression tree)
            var expression = options.ApplyTo(EmptyQueryable, QueryResultDefaults.DefaultQuerySettings).Expression;

            // Unravel the comparisons into a list we can reason about
            List<Tuple<Target, string>> comparisons = new List<Tuple<Target, string>>();
            Expression remnant = FindQueryableWhere(expression as MethodCallExpression);
            MethodCallExpression where;
            while (IsQueryableWhere(where = remnant as MethodCallExpression))
            {
                var extractedComparisons = ExtractComparison(where).ToList();
                if (!extractedComparisons.Any() || extractedComparisons.Any(c => c == null))
                {
                    hijackable = null;
                    return false;
                }
                else
                {
                    // We recognize this comparison, record it and keep iterating on the nested expression
                    comparisons.AddRange(extractedComparisons);
                    remnant = where.Arguments[0];
                }
            }

            // We should be able to hijack here
            if (comparisons.Any())
            {
                hijackable = new HijackableQueryParameters();
                foreach (var comparison in comparisons)
                {
                    if (comparison.Item1 == Target.Id)
                    {
                        hijackable.Id = comparison.Item2;
                    }
                    else if (comparison.Item1 == Target.Version)
                    {
                        hijackable.Version = comparison.Item2;
                    }
                    else
                    {
                        hijackable = null;
                        return false;
                    }
                }

                return true;
            }

            hijackable = null;
            return false;
        }