public void ClearBlockMatchup()
        {
            if (m_currentRefBlockMatchups == null)
            {
                return;
            }
            BlockGroupingStyle = BlockGroupingType.Quote;
            var relevant = IsCurrentBlockRelevant;

            m_currentRefBlockMatchups = null;
            if (!relevant)
            {
                m_temporarilyIncludedBlock = GetCurrentBlockIndices();
            }
            if (CurrentBlockMatchupChanged != null)
            {
                CurrentBlockMatchupChanged(this, new EventArgs());
            }
        }
        public void SetBlockMatchupForCurrentVerse()
        {
            if (!AttemptRefBlockMatchup || CurrentBook.SingleVoice)
            {
                return;
            }

            var origValue = m_currentRefBlockMatchups;

            m_currentRefBlockMatchups = m_project.ReferenceText.GetBlocksForVerseMatchedToReferenceText(CurrentBook,
                                                                                                        CurrentBlockIndexInBook, m_project.Versification);
            if (m_currentRefBlockMatchups != null)
            {
                m_currentRefBlockMatchups.MatchAllBlocks(m_project.Versification);
                // REVIEW: We might want to keep track of which style the user prefers.
                BlockGroupingStyle = BlockGroupingType.BlockCorrelation;
            }
            if (CurrentBlockMatchupChanged != null && origValue != m_currentRefBlockMatchups)
            {
                CurrentBlockMatchupChanged(this, new EventArgs());
            }
        }
        private bool IsRelevant(Block block, bool ignoreExcludeUserConfirmed = false)
        {
            if (block.MultiBlockQuote == MultiBlockQuote.Continuation || block.MultiBlockQuote == MultiBlockQuote.ChangeOfDelivery)
            {
                return(false);
            }
            if (!ignoreExcludeUserConfirmed && (Mode & BlocksToDisplay.ExcludeUserConfirmed) > 0 && block.UserConfirmed)
            {
                return(false);
            }
            if ((Mode & BlocksToDisplay.NeedAssignments) > 0)
            {
                return(BlockNeedsAssignment(block));
            }
            if ((Mode & BlocksToDisplay.NotAlignedToReferenceText) > 0)
            {
                if (!block.IsScripture)
                {
                    return(false);
                }

                if (s_lastMatchup == null || !s_lastMatchup.OriginalBlocks.Contains(block))
                {
                    s_lastMatchup = m_project.ReferenceText.GetBlocksForVerseMatchedToReferenceText(CurrentBook,
                                                                                                    m_navigator.GetIndicesOfSpecificBlock(block).BlockIndex, m_project.Versification);
                }
                return(s_lastMatchup.OriginalBlocks.Count() > 1 && !s_lastMatchup.CorrelatedBlocks.All(b => b.MatchesReferenceText));
            }
            if ((Mode & BlocksToDisplay.AllExpectedQuotes) > 0)
            {
                return(IsBlockInVerseWithExpectedQuote(block));
            }
            if ((Mode & BlocksToDisplay.MissingExpectedQuote) > 0)
            {
                if (CurrentBookIsSingleVoice)
                {
                    return(false);
                }

                if (block.IsQuote || CharacterVerseData.IsCharacterExtraBiblical(block.CharacterId))
                {
                    return(false);
                }

                IEnumerable <BCVRef> versesWithPotentialMissingQuote =
                    ControlCharacterVerseData.Singleton.GetCharacters(CurrentBookId, block.ChapterNumber, block.InitialStartVerseNumber,
                                                                      block.LastVerseNum, versification: Versification).Where(c => c.IsExpected).Select(c => c.BcvRef);

                var withPotentialMissingQuote = versesWithPotentialMissingQuote as IList <BCVRef> ?? versesWithPotentialMissingQuote.ToList();
                if (!withPotentialMissingQuote.Any())
                {
                    return(false);
                }

                // REVIEW: This method peeks forward/backward from the *CURRENT* block, which might not be the block passed in to this method.
                return(CurrentBlockHasMissingExpectedQuote(withPotentialMissingQuote));
            }
            if ((Mode & BlocksToDisplay.MoreQuotesThanExpectedSpeakers) > 0)
            {
                if (!block.IsQuote || CurrentBookIsSingleVoice)
                {
                    return(false);
                }

                var expectedSpeakers = ControlCharacterVerseData.Singleton.GetCharacters(CurrentBookId, block.ChapterNumber, block.InitialStartVerseNumber,
                                                                                         block.InitialEndVerseNumber, versification: Versification).Distinct(new CharacterEqualityComparer()).Count();

                var actualquotes = 1;                 // this is the quote represented by the given block.

                if (actualquotes > expectedSpeakers)
                {
                    return(true);
                }

                // REVIEW: This method peeks forward/backward from the *CURRENT* block, which might not be the block passed in to this method.
                // Check surrounding blocks to count quote blocks for same verse.
                actualquotes += m_navigator.PeekBackwardWithinBookWhile(b => b.ChapterNumber == block.ChapterNumber &&
                                                                        b.InitialStartVerseNumber == block.InitialStartVerseNumber)
                                .Count(b => b.IsQuote && (b.MultiBlockQuote == MultiBlockQuote.Start || b.MultiBlockQuote == MultiBlockQuote.None));

                if (actualquotes > expectedSpeakers)
                {
                    return(true);
                }

                actualquotes += m_navigator.PeekForwardWithinBookWhile(b => b.ChapterNumber == block.ChapterNumber &&
                                                                       b.InitialStartVerseNumber == block.InitialStartVerseNumber)
                                .Count(b => b.IsQuote && (b.MultiBlockQuote == MultiBlockQuote.Start || b.MultiBlockQuote == MultiBlockQuote.None));

                return(actualquotes > expectedSpeakers);
            }
            if ((Mode & BlocksToDisplay.AllScripture) > 0)
            {
                return(block.IsScripture);
            }
            if ((Mode & BlocksToDisplay.AllQuotes) > 0)
            {
                return(block.IsQuote);
            }
            return(false);
        }