public IEnumerable <Character> GetCharactersForCurrentReference(bool expandIfNone = true)
        {
            m_currentCharacters = GetUniqueCharactersForCurrentReference();

            var listToReturn = new List <Character>(new SortedSet <Character>(
                                                        m_currentCharacters.Select(cv => new Character(cv.Character, cv.LocalizedCharacter, cv.Alias, cv.LocalizedAlias, cv.ProjectSpecific)), m_characterComparer));

            listToReturn.Sort(m_aliasComparer);

            if (listToReturn.All(c => !c.IsNarrator))
            {
                listToReturn.Add(Character.Narrator);
            }

            if (m_currentCharacters.Count == 0 && expandIfNone)
            {
                // This will get any expected characters from other verses in the current block.
                var block = CurrentBlock;
                foreach (var character in m_combinedCharacterVerseData.GetCharacters(CurrentBookId, block.ChapterNumber,
                                                                                     block.InitialStartVerseNumber, block.LastVerse, versification: Versification))
                {
                    m_currentCharacters.Add(character);
                }

                var listToAdd = new SortedSet <Character>(m_currentCharacters.Select(cv =>
                                                                                     new Character(cv.Character, cv.LocalizedCharacter, cv.Alias, cv.LocalizedAlias)), m_characterComparer).Where(c => !listToReturn.Contains(c)).ToList();
                listToAdd.Sort(m_aliasComparer);
                listToReturn.AddRange(listToAdd);
            }

            if (m_currentCharacters.Count == 0 && expandIfNone)
            {
                // This will get any potential or actual characters from surrounding material.
                foreach (var block in ContextBlocksBackward.Union(ContextBlocksForward))
                {
                    foreach (var character in m_combinedCharacterVerseData.GetCharacters(CurrentBookId, block.ChapterNumber,
                                                                                         block.InitialStartVerseNumber, block.InitialEndVerseNumber, versification: Versification))
                    {
                        m_currentCharacters.Add(character);
                    }
                }

                var listToAdd = new SortedSet <Character>(m_currentCharacters.Select(cv =>
                                                                                     new Character(cv.Character, cv.LocalizedCharacter, cv.Alias, cv.LocalizedAlias)), m_characterComparer).Where(c => !listToReturn.Contains(c)).ToList();
                listToAdd.Sort(m_aliasComparer);
                listToReturn.AddRange(listToAdd);
            }

            return(m_generatedCharacterList = listToReturn);
        }
        private IEnumerable <Character> GetUniqueCharacters(bool expandIfNone = true)
        {
            var listToReturn = new List <Character>(new SortedSet <Character>(
                                                        m_currentCharacters.Select(cv => new Character(cv.Character, cv.LocalizedCharacter, cv.Alias, cv.LocalizedAlias, cv.ProjectSpecific)), m_characterComparer));

            listToReturn.Sort(m_aliasComparer);

            if (listToReturn.All(c => !c.IsNarrator))
            {
                listToReturn.Insert(0, Character.Narrator);
            }

            if (m_currentCharacters.Count == 0 && expandIfNone)
            {
                // This will get any expected characters from other verses in the current block.
                var block = CurrentBlock;
                CollectionExtensions.AddRange(m_currentCharacters, m_combinedCharacterVerseData.GetCharacters(CurrentBookNumber, block.ChapterNumber,
                                                                                                              new[] { (Block.VerseRangeFromBlock)block }, Versification, true));

                var listToAdd = new SortedSet <Character>(m_currentCharacters.Select(cv =>
                                                                                     new Character(cv.Character, cv.LocalizedCharacter, cv.Alias, cv.LocalizedAlias)), m_characterComparer).Where(c => !listToReturn.Contains(c)).ToList();
                listToAdd.Sort(m_aliasComparer);
                listToReturn.AddRange(listToAdd);
            }

            if (m_currentCharacters.Count == 0 && expandIfNone)
            {
                // This will get any potential or actual characters from surrounding material.
                foreach (var block in ContextBlocksBackward.Union(ContextBlocksForward))
                {
                    m_currentCharacters.UnionWith(m_combinedCharacterVerseData.GetCharacters(CurrentBookNumber, block.ChapterNumber,
                                                                                             (Block.VerseRangeFromBlock)block, Versification, true));
                }

                var listToAdd = new SortedSet <Character>(m_currentCharacters.Select(cv =>
                                                                                     new Character(cv.Character, cv.LocalizedCharacter, cv.Alias, cv.LocalizedAlias)), m_characterComparer).Where(c => !listToReturn.Contains(c)).ToList();
                listToAdd.Sort(m_aliasComparer);
                listToReturn.AddRange(listToAdd);
            }

            return(m_generatedCharacterList = listToReturn);
        }