/// <summary>
        /// Extracts the filter definition once a leaf is found.
        /// </summary>
        /// <param name="info">QueryInformation being filled.</param>
        /// <param name="binaryNode">BinaryOperatorNode the leaf belongs to.</param>
        /// <param name="constantNode">ConstantNode with the parameter definition.</param>
        private void ProcessLeafNode(QueryInformation info, BinaryOperatorNode binaryNode, ConstantNode constantNode)
        {
            try
            {
                // Necesary variables
                SingleValuePropertyAccessNode propertyAccessNode = binaryNode.Left as SingleValuePropertyAccessNode;
                SingleValueFunctionCallNode   functioncall       = binaryNode.Left as SingleValueFunctionCallNode;

                // The filter definition that is going to be added.
                FilterParameterDefinition filterdefinition = new FilterParameterDefinition();

                // Populating common values.
                filterdefinition.FilteringOperator = (FilteringOperator)binaryNode.OperatorKind;
                filterdefinition.StringValue       = constantNode.Value.ToString();


                if (functioncall != null)
                {
                    // it contains a function call
                    propertyAccessNode = ParseFunctionCall(propertyAccessNode, functioncall, filterdefinition);
                }

                if (propertyAccessNode != null)
                {
                    //it is a simple equals
                    ParsePropertyAccessNode(info, propertyAccessNode, filterdefinition);
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }
        /// <summary>
        /// Parses an ODataQueryOptions objects exposing its features in a custom object.
        /// </summary>
        /// <param name="options">ODataQueryOptions given by the ASP.NET Web Odata API controller.</param>
        /// <returns>A QueryInformation containing the parsing results.</returns>
        /// <remarks>
        /// We currently support only the Filter aspects of the ODataQueryOptions object.
        /// </remarks>
        public QueryInformation Parse(ODataQueryOptions options)
        {
            QueryInformation info = new QueryInformation();

            ParseFilterData(options.Filter, info);

            return(info);
        }
        /// <summary>
        /// Performs a Binary search on the abstract syntax tree of the filter expression.
        /// </summary>
        /// <param name="node">The node that needs to be searched on.</param>
        /// <param name="info">The QueryInformation where we are accumulating the filter definitions. </param>
        private void BinarySearchForNodes(QueryNode node, QueryInformation info)
        {
            try
            {
                var binaryNode = node as BinaryOperatorNode;

                if (binaryNode != null)
                {
                    // We look for constant nodes that would mean a leaf have been reached.
                    ConstantNode constantNode = GetConstantNode(binaryNode);

                    if (constantNode != null)
                    {
                        ProcessLeafNode(info, binaryNode, constantNode);
                    }
                    else
                    {
                        BinarySearchForNodes(binaryNode.Left, info);
                        BinarySearchForNodes(binaryNode.Right, info);
                    }
                }
                else
                {
                    var convertNode = node as ConvertNode;

                    if (convertNode != null)
                    {
                        BinarySearchForNodes(convertNode.Source, info);
                    }
                    else
                    {
                        LogWarning(string.Format("Node wasn't casted as binary node. Type is {0}", node.GetType().FullName));
                    }
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }
        /// <summary>
        /// Parses the Filter portion of the ODataQueryOptions object and adds its details to the used QueryInformation.
        /// </summary>
        /// <param name="filter">FilterQueryOption object contained in the ODataQueryOptions from the OData controller.</param>
        /// <param name="info">The QueryInformation object that is maintained to give back the results.</param>
        public void ParseFilterData(FilterQueryOption filter, QueryInformation info)
        {
            try
            {
                // If the filter comes null, there is no work to be done by this method.
                if (filter == null)
                {
                    return;
                }

                // There is at least one parameter so we instantiate the collection in the info object.
                info.FilterParameters = new ODataFilterParameterCollection();

                // The abstract syntax tree of the expression is a binary tree, we perform it here from the root.
                BinarySearchForNodes(filter.FilterClause.Expression, info);

                return;
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }
        /// <summary>
        /// Parses a Property access node.
        /// </summary>
        /// <param name="info">QueryInformation being filled.</param>
        /// <param name="propertyAccessNode">Property access node to be parsed.</param>
        /// <param name="filterdefinition">Filter definition being filled.</param>
        private static void ParsePropertyAccessNode(QueryInformation info, SingleValuePropertyAccessNode propertyAccessNode, FilterParameterDefinition filterdefinition)
        {
            filterdefinition.FieldName = propertyAccessNode.Property.Name;

            info.FilterParameters.Add(filterdefinition);
        }