/// <summary>
        /// Parses the source code searching for the longest matching term text from the specified terms.
        /// It returns the index of the longest matching term or -1, if there is no matching term at the specified source position.
        /// </summary>
        /// <param name="source">The source of an extension.</param>
        /// <param name="textSelector">The selector of term text at the specified 0 based index.</param>
        /// <param name="accept">if set to <c>true</c> accepts the position after parsed longest text.</param>
        /// <param name="charComparer">The character comparer.</param>
        /// <param name="termsCount">The number of terms.</param>
        /// <returns>The index of the longest matching text or -1, if there is no matching text at the specified source position.</returns>
        public static int ParseLongestMatchingString(this IParsingContextStream source, int termsCount, Func <int, string> textSelector, bool accept = false, IEqualityComparer <char> charComparer = null)
        {
            var text           = Enumerable.Range(0, termsCount).Select(textSelector).ToArray();
            var matchedTermIdx = -1;

            using (var ctx = source.GetFurtherContext())
            {
                //go through all character indexes from 0 to longest matching term
                //  for each term check if character at specified position matches
                //      if char matches and it is last character, temporary accept position and exclude term by setting to null
                //      if char doesn't match -> exclude term by setting to null
                //  if there are no more matching terms -> break
                //  if accept true and matchedTermIdx > -1 -> accept
                // return matchedTermIndex

                var charPosition = -1;
                while (ctx.MoveNext())
                {
                    charPosition++;
                    var current            = ctx.Current;
                    var matchingTermsCount = 0;
                    for (var termIdx = 0; termIdx < text.Length; termIdx++)
                    {
                        var currentTerm = text[termIdx];

                        if (currentTerm != null)
                        {
                            if (currentTerm.Length <= charPosition)
                            {
                                text[termIdx] = null;
                            }

                            if (Equals(currentTerm[charPosition], current, charComparer))
                            {
                                if (currentTerm.Length == charPosition + 1)
                                {
                                    matchedTermIdx = termIdx;
                                    ctx.Accept();
                                    text[termIdx] = null;
                                }
                                else
                                {
                                    matchingTermsCount++;
                                }
                            }
                            else
                            {
                                text[termIdx] = null;
                            }
                        }
                    }

                    if (matchingTermsCount <= 0)
                    {
                        break;
                    }
                }
            }

            if (accept && matchedTermIdx >= 0)
            {
                source.Accept();
            }

            return(matchedTermIdx);
        }