/// <summary>
        /// Retrieves the filter definition from the expression
        /// </summary>
        /// <param name="expression">Filter expression</param>
        /// <returns>A filter definition based on an expression</returns>
        internal static FilterDefinition FromExpression(String expression)
        {
            List<string> filterTokens = expression.TrimmedSplit("|");

            // Invalid number of segments
            if (filterTokens.Count != 1 && filterTokens.Count != 2)
                throw new InvalidFilterDefinitionException(
                    InvalidFilterDefinitionException.ErrorCause.InvalidNumberOfDefinitionElements);

            // Missing function name or arguments
            if (filterTokens.Count == 1 && expression.Contains("|"))
                throw new InvalidFilterDefinitionException(
                    InvalidFilterDefinitionException.ErrorCause.FunctionNameOrArgumentMissing);

            string functionName = filterTokens.First();

            if (functionName.ContainsWhitespace())
                throw new InvalidFilterDefinitionException(
                    InvalidFilterDefinitionException.ErrorCause.FunctionNameContainsWhitespace,
                    functionName);

            FilterDefinition definition = new FilterDefinition(functionName);

            if (filterTokens.Count == 2)
            {
                List<string> arguments = filterTokens[1].TrimmedSplit(",");

                List<FilterArgumentDefinition> argumentDefinitions =
                    arguments
                    .Select(a => FilterArgumentDefinition.FromArgumentExpression(a))
                    .ToList();

                definition.Arguments.AddRange(argumentDefinitions);
            }

            return definition;
        }
        /// <summary>
        /// Checks whether the item should be included in the output
        /// </summary>
        /// <param name="filterDefinition">A filter definition object with name and arguments</param>
        /// <param name="behavior">Specifies what happens when a filter is missing</param>
        /// <returns>True if current item should be included</returns>
        internal bool IsIncludedWithFilter(FilterDefinition filterDefinition, MissingFilterBehavior behavior)
        {
            if (!filterMap.ContainsKey(filterDefinition.Function))
            {
                switch (behavior)
                {
                    case MissingFilterBehavior.IncludeItem:
                        return true;
                    case MissingFilterBehavior.OmitItem:
                        return false;
                    case MissingFilterBehavior.ThrowException:
                    default:
                        throw new FilterNotFoundException(filterDefinition.Function);
                }
            }

            // Find a filter
            FilterFunction predicate = filterMap[filterDefinition.Function];

            // Create filter arguments
            IEnumerable<CollapseFilterArgument> arguments =
                filterDefinition.Arguments
                .Select(arg => new CollapseFilterArgument(GetObject(arg.Path), arg.Name));

            // Run the predicate to see if the item should be included
            return predicate(
                new CollapseFilterArgumentCollection(arguments));
        }