public void AnalyzeBlock(
			Block block,
			int blockVersion)
        {
            // Grab the information about the block.
            string text;
            var originalMispelledWords = new TextSpanCollection();

            using (block.AcquireBlockLock(RequestLock.Read))
            {
                // If we are stale, then break out.
                if (block.IsStale(blockVersion))
                {
                    return;
                }

                // Grab the information from the block. We need the text and
                // alow the current spelling areas.
                text = block.Text;

                originalMispelledWords.AddRange(
                    block.TextSpans.Where(span => span.Controller == this));
            }

            // Split the word and perform spell-checking.
            var misspelledWords = new List<TextSpan>();
            IList<TextSpan> words = Splitter.SplitAndNormalize(text);
            IEnumerable<TextSpan> misspelledSpans =
                words.Where(span => !IsCorrect(span.GetText(text)));

            foreach (TextSpan span in misspelledSpans)
            {
                // We aren't correct, so add it to the list.
                span.Controller = this;

                misspelledWords.Add(span);
            }

            // Look to see if we have any change from the original spelling
            // errors and this one. This will only happen if the count is
            // identical and every one in the original list is in the new list.
            if (originalMispelledWords.Count == misspelledWords.Count)
            {
                bool isMatch = originalMispelledWords.All(misspelledWords.Contains);

                if (isMatch)
                {
                    // There are no new changes, so we don't have anything to
                    // update.
                    return;
                }
            }

            // Inside a write lock, we need to make modifications to the block's list.
            using (block.AcquireBlockLock(RequestLock.Write))
            {
                // Check one last time to see if the block is stale.
                if (block.IsStale(blockVersion))
                {
                    return;
                }

                // Make the changes to the block's contents.
                block.TextSpans.Remove(this);
                block.TextSpans.AddRange(misspelledWords);

                // Raise that we changed the spelling on the block.
                block.RaiseTextSpansChanged();
            }
        }
        /// <summary>
        /// Analyzes the block and counts the word. Once counted, this updates
        /// the block and all parent blocks with the altered change.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="blockVersion">The block version of the initial request.</param>
        public void AnalyzeBlock(
			Block block,
			int blockVersion)
        {
            // Grab counts from the current block text.
            int newCount = 1;
            int newWordCount;
            int newCharacterCount;
            int newNonWhitespaceCount;
            string text = block.Text;

            WordCounter.CountWords(
                text, out newWordCount, out newCharacterCount, out newNonWhitespaceCount);

            // Grab the existing counts from the current block, if we have one.
            int oldCount;
            int oldWordCount;
            int oldCharacterCount;
            int oldNonWhitespaceCount;

            WordCounterPathUtility.GetCounts(
                this,
                block,
                out oldCount,
                out oldWordCount,
                out oldCharacterCount,
                out oldNonWhitespaceCount);

            // Calculate the deltas between the values.
            int delta = newCount - oldCount;
            int wordDelta = newWordCount - oldWordCount;
            int characterDelta = newCharacterCount - oldCharacterCount;
            int nonWhitespaceDelta = newNonWhitespaceCount - oldNonWhitespaceCount;

            // Build up a dictionary of changes so we can have a simple loop to
            // set them in the various elements.
            Dictionary<HierarchicalPath, int> deltas =
                WordCounterPathUtility.GetDeltas(
                    this, block, delta, wordDelta, characterDelta, nonWhitespaceDelta);

            // Get a write lock on the blocks list and update that block and all
            // parent blocks in the document.
            using (block.AcquireBlockLock(RequestLock.Write))
            {
                // Log that we are analyzing this block.
                Log("BEGIN AnalyzeBlock: {0}: Words {1:N0}", block, newWordCount);

                // First check to see if we've gotten stale.
                if (block.IsStale(blockVersion))
                {
                    return;
                }

                // Update the block and the document.
                UpdateDeltas(block, deltas);
                UpdateDeltas(block.Project, deltas);

                // Log that we finished processing this block.
                Log("END   AnalyzeBlock: {0}: Words {1:N0}", block, newWordCount);
            }
        }