private bool EntryIsLikeVerse(string text, int indexOfDigit, bool useCommaDelimiter)
        {
            var prevChar = StringUtils.GetChar(text, indexOfDigit - 1);
            var nextChar = StringUtils.GetCharAfterNumber(text, indexOfDigit, out int indexOfChar);

            var result = (VerseUtils.IsStartVerseChar(prevChar, useCommaDelimiter) || char.IsLetter(prevChar)) &&
                         (nextChar == default(char) || !char.IsDigit(nextChar));

            return(result);
        }
        private VerseNumberEntry TryGetTopVerseNumber(string text, int startIndex, VerseNumber verseNumber)
        {
            var cursorIndex   = startIndex;
            var dashWasFound  = false;
            var digitWasFound = false;
            var indexOfDigit  = 0;
            var maxSpaceBetweenVerseNumbers = 3;

            while (cursorIndex - startIndex <= maxSpaceBetweenVerseNumbers)
            {
                var c = StringUtils.GetChar(text, cursorIndex);

                if (VerseUtils.IsDash(c) && !dashWasFound)
                {
                    dashWasFound = true;
                }
                else if (char.IsDigit(c) && dashWasFound)
                {
                    digitWasFound = true;
                    indexOfDigit  = cursorIndex;
                    break;
                }
                else if (c != ' ')
                {
                    break;
                }

                cursorIndex++;
            }

            if (!dashWasFound || !digitWasFound)
            {
                return(null);
            }

            var result = TryGetVerseNumber(text, indexOfDigit, false);

            if (result.VerseNumber.IsChapter && !verseNumber.IsChapter)
            {
                result.VerseNumber = new VerseNumber(verseNumber.Chapter, result.VerseNumber.Chapter);
            }

            if (result.VerseNumber.Chapter < verseNumber.Chapter ||
                (result.VerseNumber.IsChapter && result.VerseNumber.Chapter == verseNumber.Chapter) ||
                (result.VerseNumber.Chapter == verseNumber.Chapter && result.VerseNumber.Verse <= verseNumber.Verse))
            {
                return(null);
            }

            return(result);
        }
        private int GetBookEndIndex(string text, int indexOfDigit)
        {
            var endIndex      = indexOfDigit - 1;
            var maxMidSymbols = 4;

            while (endIndex > 0 && !char.IsLetter(text[endIndex]))
            {
                if (VerseUtils.IsMidVerseChar(text[endIndex]) && indexOfDigit - endIndex <= (maxMidSymbols + 1))
                {
                    endIndex--;
                }
                else
                {
                    break;
                }
            }

            return(endIndex);
        }
        private VerseNumberEntry TryGetVerseNumber(string text, int indexOfDigit, bool useCommaDelimiter)
        {
            char[] chapterDigits         = new char[3];
            char[] verseDigits           = new char[3];
            var    chapterIndex          = 0;
            var    verseIndex            = 0;
            var    chapterWasFound       = false;
            var    spaceWasFound         = false;
            var    cursorIndex           = indexOfDigit;
            var    maxVerseNumberLength  = 9;
            var    lastValuableCharIndex = 0;

            while (cursorIndex - indexOfDigit + 1 <= maxVerseNumberLength)
            {
                var c = StringUtils.GetChar(text, cursorIndex);

                if (char.IsDigit(c))
                {
                    if (!chapterWasFound)
                    {
                        if (chapterIndex >= chapterDigits.Length)
                        {
                            break;
                        }

                        chapterDigits[chapterIndex++] = c;
                    }
                    else
                    {
                        if (verseIndex >= verseDigits.Length)
                        {
                            break;
                        }

                        verseDigits[verseIndex++] = c;
                    }

                    lastValuableCharIndex = cursorIndex;
                    spaceWasFound         = false;
                }
                else if (c == ' ' && !spaceWasFound)
                {
                    spaceWasFound = true;
                }
                else if (VerseUtils.IsChapterVerseDelimiter(c, useCommaDelimiter) && !chapterWasFound)
                {
                    chapterWasFound = true;
                    spaceWasFound   = false;
                }
                else
                {
                    break;
                }

                cursorIndex++;
            }

            var chapter = VerseUtils.GetVerseNumber(chapterDigits, chapterIndex);
            var verse   = VerseUtils.GetVerseNumber(verseDigits, verseIndex);

            return(new VerseNumberEntry()
            {
                StartIndex = indexOfDigit,
                EndIndex = lastValuableCharIndex,
                VerseNumber = new VerseNumber(chapter, verse)
            });
        }