public static void GetBeginAndEndCharacterIndices(
            this SingleLineTextRange range,
            ProjectBlockCollection blocks,
            out int blockIndex,
            out int sourceBegin,
            out int sourceEnd,
            out string text)
        {
            using (blocks.AcquireLock(RequestLock.Read))
            {
                // Start by getting the block based on the index.
                Block block;

                blockIndex = range.LinePosition.GetLineIndex(blocks.Count);

                using (
                    blocks.AcquireBlockLock(
                        RequestLock.Read, RequestLock.Read, blockIndex, out block))
                {
                    // Get the text and calculate the character indicies.
                    text = block.Text;

                    range.GetBeginAndEndCharacterIndices(text, out sourceBegin, out sourceEnd);
                }
            }
        }
        /// <summary>
        /// Writes out the project file to a given directory.
        /// </summary>
        /// <param name="directory">The directory to save the file.</param>
        public void Save(DirectoryInfo directory)
        {
            // Set up the project macros we'll be expanding.
            ProjectMacros macros = SetupMacros(directory);

            // Validate the state.
            string projectFilename = macros.ExpandMacros("{ProjectFilename}");

            if (string.IsNullOrWhiteSpace(projectFilename))
            {
                throw new InvalidOperationException(
                          "Project filename is not defined in Settings property.");
            }

            // We need a write lock on the blocks to avoid changes. This also prevents
            // any background tasks from modifying the blocks during the save process.
            ProjectBlockCollection blocks = Project.Blocks;

            using (blocks.AcquireLock(RequestLock.Write))
            {
                // Create a new project writer and write out the results.
                var projectWriter = new FilesystemPersistenceProjectWriter(
                    Project, Settings, macros);
                var projectFile = new FileInfo(projectFilename);

                projectWriter.Write(projectFile);
            }
        }
        public void Undo(BlockCommandContext context)
        {
            // Since we're making chanegs to the list, we need a write lock.
            ProjectBlockCollection blocks = context.Blocks;

            using (blocks.AcquireLock(RequestLock.Write))
            {
                // Go through all the blocks in the project.
                foreach (Block block in blocks)
                {
                    if (Changes.ContainsKey(block.BlockKey))
                    {
                        // Revert the type of this block.
                        BlockType blockType = previousBlockTypes[block.BlockKey];

                        block.SetBlockType(blockType);
                    }
                }
            }
        }
        public void Do(BlockCommandContext context)
        {
            // Since we're making chanegs to the list, we need a write lock.
            ProjectBlockCollection blocks = context.Blocks;

            using (blocks.AcquireLock(RequestLock.Write))
            {
                // Clear out the undo list since we'll be rebuilding it.
                previousBlockTypes.Clear();

                // Go through all the blocks in the project.
                foreach (Block block in blocks)
                {
                    if (Changes.ContainsKey(block.BlockKey))
                    {
                        BlockType blockType    = Changes[block.BlockKey];
                        BlockType existingType = block.BlockType;

                        previousBlockTypes[block.BlockKey] = existingType;
                        block.SetBlockType(blockType);
                    }
                }
            }
        }