/// <summary>
        /// Creates a <see cref="PropertyReader"/> by parsing the combinedToken parameter.
        /// </summary>
        /// <param name="combinedToken">A combined token</param>
        /// <param name="propertyReaderFactory">A factory object used to construct property readers from</param>
        /// <returns>Usually returns a <see cref="CombinedPropertyReader"/> but can optimise to return a specific <see cref="PropertyReader"/>
        /// or <see cref="LiteralPropertyReader"/> if there is no need for a combined version</returns>
        public PropertyReader Create(string combinedToken, IPropertyReaderFactory propertyReaderFactory)
        {
            if (combinedToken == null)
            {
                throw new ArgumentNullException("combinedToken");
            }

            MatchCollection matches = _matchesTokens.Matches(combinedToken);

            // Is the whole format string just a single token? If so, return that single property reader
            if (matches.Count == 1
                && matches[0].Length == combinedToken.Trim().Length)
            {
                Token token = new Token(matches[0].Value);
                return CreateReaderOrLiteral(propertyReaderFactory, token);
            }

            // if no tokens, just return a literalpropertyreader
            if (matches.Count == 0)
            {
                return new LiteralPropertyReader(combinedToken);
            }

            CombinedPropertyReader reader = new CombinedPropertyReader();

            int cursor = 0;

            foreach (Match match in matches)
            {
                if (match.Index > cursor)
                {
                    reader.PropertyReaders.Add(
                        new LiteralPropertyReader(combinedToken.Substring(cursor, match.Index - cursor)));
                }

                Token token = new Token(match.Value);
                reader.PropertyReaders.Add(CreateReaderOrLiteral(propertyReaderFactory, token));
                cursor = match.Index + match.Length;
            }
            if (combinedToken.Length > cursor)
            {
                reader.PropertyReaders.Add(
                    new LiteralPropertyReader(combinedToken.Substring(cursor, combinedToken.Length - cursor)));
            }


            return reader;
        }
        /// <summary>
        /// Creates a <see cref="PropertyReader"/> by parsing the combinedToken parameter.
        /// </summary>
        /// <param name="combinedToken">A combined token</param>
        /// <param name="propertyReaderFactory">A factory object used to construct property readers from</param>
        /// <returns>Usually returns a <see cref="CombinedPropertyReader"/> but can optimise to return a specific <see cref="PropertyReader"/>
        /// or <see cref="LiteralPropertyReader"/> if there is no need for a combined version</returns>
        public PropertyReader Create(string combinedToken, IPropertyReaderFactory propertyReaderFactory)
        {
            if (combinedToken == null)
            {
                throw new ArgumentNullException("combinedToken");
            }

            MatchCollection matches = _matchesTokens.Matches(combinedToken);

            // Is the whole format string just a single token? If so, return that single property reader
            if (matches.Count == 1 &&
                matches[0].Length == combinedToken.Trim().Length)
            {
                Token token = new Token(matches[0].Value);
                return(CreateReaderOrLiteral(propertyReaderFactory, token));
            }

            // if no tokens, just return a literalpropertyreader
            if (matches.Count == 0)
            {
                return(new LiteralPropertyReader(combinedToken));
            }

            CombinedPropertyReader reader = new CombinedPropertyReader();

            int cursor = 0;

            foreach (Match match in matches)
            {
                if (match.Index > cursor)
                {
                    reader.PropertyReaders.Add(
                        new LiteralPropertyReader(combinedToken.Substring(cursor, match.Index - cursor)));
                }

                Token token = new Token(match.Value);
                reader.PropertyReaders.Add(CreateReaderOrLiteral(propertyReaderFactory, token));
                cursor = match.Index + match.Length;
            }
            if (combinedToken.Length > cursor)
            {
                reader.PropertyReaders.Add(
                    new LiteralPropertyReader(combinedToken.Substring(cursor, combinedToken.Length - cursor)));
            }


            return(reader);
        }