protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            // Save the previous text so we can restore it.
            previousText = block.Text;
            originalPosition = context.Position;

            // Figure out what the new text string would be.
            startIndex = BlockPosition.TextIndex.GetCharacterIndex(
                block.Text, End, WordSearchDirection.Left);
            int endIndex = End.GetCharacterIndex(
                block.Text, TextIndex, WordSearchDirection.Right);

            int firstIndex = Math.Min(startIndex, endIndex);
            int lastIndex = Math.Max(startIndex, endIndex);
            string newText = block.Text.Remove(firstIndex, lastIndex - firstIndex);

            // Set the new text into the block. This will fire various events to
            // trigger the immediate and background processing.
            block.SetText(newText);

            // Set the position after the next text.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, startIndex);
            }
        }
        /// <summary>
        /// Performs the command on the given block.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="block">The block to perform the action on.</param>
        /// <param name="project">The project that contains the current state.</param>
        protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            // Save the previous text so we can undo it.
            previousText = block.Text;

            // Figure out what the new text string would be.
            int textIndex = new CharacterPosition(TextIndex).GetCharacterIndex(
                block.Text);
            string newText = block.Text.Insert(textIndex, Text);

            // Set the new text into the block. This will fire various events to
            // trigger the immediate and background processing.
            block.SetText(newText);

            // After we insert text, we need to give the immediate editor plugins a
            // chance to made any alterations to the output.
            block.Project.Plugins.ProcessImmediateEdits(
                context, block, textIndex + Text.Length);

            // Set the new position in the buffer.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, textIndex + Text.Length);
            }
        }
        protected override void Undo(
			BlockCommandContext context,
			Block block)
        {
            block.SetText(previousText);
            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = new BlockPosition(BlockKey, previousText.Length);
            }
        }
        protected override void Do(
			BlockCommandContext context,
			Block block)
        {
            previousText = block.Text;
            block.SetText(Text);

            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = new BlockPosition(BlockKey, Text.Length);
            }
        }
        /// <summary>
        /// Inserts the lines.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <param name="lineCount">The line count.</param>
        private void InsertLines(
			Project project,
			int lineCount)
        {
            // Pull out some useful variables.
            ProjectBlockCollection blocks = project.Blocks;

            // Modify the first line, which is always there.
            using (blocks[0].AcquireBlockLock(RequestLock.Write))
            {
                blocks[0].SetText("Line 1");
            }

            // Add in the additional lines after the first one.
            for (int i = 1;
                i < lineCount;
                i++)
            {
                var block = new Block(blocks);
                using (block.AcquireBlockLock(RequestLock.Write))
                {
                    block.SetText("Line " + (i + 1));
                }
                blocks.Add(block);
            }
        }
        public void Do(BlockCommandContext context)
        {
            // We have to clear the undo buffer every time because we'll be creating
            // new blocks.
            addedBlocks.Clear();

            // Start by breaking apart the lines on the newline.
            string[] lines = Text.Split('\n');

            // Make changes to the first line by creating a command, adding it to the
            // list of commands we need an inverse for, and then performing it.
            Block block = context.Blocks[BlockPosition.BlockKey];
            string remainingText = block.Text.Substring((int) BlockPosition.TextIndex);
            deleteFirstCommand = new DeleteTextCommand(BlockPosition, block.Text.Length);
            insertFirstCommand = new InsertTextCommand(BlockPosition, lines[0]);

            deleteFirstCommand.Do(context);
            insertFirstCommand.Do(context);

            // Update the final lines text with the remains of the first line.
            int lastLineLength = lines[lines.Length - 1].Length;
            lines[lines.Length - 1] += remainingText;

            // For the remaining lines, we need to insert each one in turn.
            if (UpdateTextPosition.HasFlag(DoTypes.Do))
            {
                context.Position = BlockPosition.Empty;
            }

            if (lines.Length > 1)
            {
                // Go through all the lines in reverse order to insert them.
                int firstBlockIndex = context.Blocks.IndexOf(block);

                for (int i = lines.Length - 1;
                    i > 0;
                    i--)
                {
                    // Insert the line and set its text value.
                    var newBlock = new Block(context.Blocks);

                    addedBlocks.Add(newBlock);

                    using (newBlock.AcquireBlockLock(RequestLock.Write))
                    {
                        newBlock.SetText(lines[i]);
                    }

                    context.Blocks.Insert(firstBlockIndex + 1, newBlock);

                    // Update the last position as we go.
                    if (context.Position == BlockPosition.Empty)
                    {
                        if (UpdateTextPosition.HasFlag(DoTypes.Do))
                        {
                            context.Position = new BlockPosition(
                                newBlock.BlockKey, (CharacterPosition) lastLineLength);
                        }
                    }
                }
            }
        }
        protected override void Undo(
			BlockCommandContext context,
			Block block)
        {
            block.SetText(previousText);

            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = originalPosition;
            }
        }
        protected override void Undo(
			BlockCommandContext context,
			Block block)
        {
            block.SetText(previousText);

            // Set the new cursor position.
            int textIndex = BlockPosition.TextIndex.GetCharacterIndex(previousText);

            if (UpdateTextPosition.HasFlag(DoTypes.Undo))
            {
                context.Position = new BlockPosition(BlockPosition.BlockKey, textIndex);
            }
        }