public static void Serialize(OperationGraph state, System.IO.BinaryWriter writer)
        {
            // Write the File Header with version
            writer.Write(new char[] { 'B', 'O', 'G', '\0' });
            writer.Write(FileVersion);

            // Write out the set of files
            var files = state.GetReferencedFiles();

            writer.Write(new char[] { 'F', 'I', 'S', '\0' });
            writer.Write((uint)files.Count);
            foreach (var file in files)
            {
                // Write the file id + path length + path
                writer.Write(file.FileId.value);
                WriteValue(writer, file.Path.ToString());
            }

            // Write out the root operation ids
            writer.Write(new char[] { 'R', 'O', 'P', '\0' });
            WriteValues(writer, state.GetRootOperationIds());

            // Write out the set of operations
            var operations = state.GetOperations();

            writer.Write(new char[] { 'O', 'P', 'S', '\0' });
            writer.Write((uint)operations.Count);
            foreach (var operationValue in state.GetOperations())
            {
                WriteOperationInfo(writer, operationValue.Value);
            }
        }
        /// <summary>
        /// Save the operation state for the provided directory
        /// </summary>
        public static void SaveState(
            Path operationGraphFile,
            OperationGraph state,
            FileSystemState fileSystemState)
        {
            var targetFolder = operationGraphFile.GetParent();

            // Update the operation graph referenced files
            var files = new HashSet <FileId>();

            foreach (var operationReference in state.GetOperations())
            {
                var operation = operationReference.Value;
                files.UnionWith(operation.DeclaredInput);
                files.UnionWith(operation.DeclaredOutput);
                files.UnionWith(operation.ReadAccess);
                files.UnionWith(operation.WriteAccess);
                files.UnionWith(operation.ObservedInput);
                files.UnionWith(operation.ObservedOutput);
            }

            var referencedFiles = new List <(FileId FileId, Path Path)>();

            foreach (var fileId in files)
            {
                referencedFiles.Add((fileId, fileSystemState.GetFilePath(fileId)));
            }

            state.SetReferencedFiles(referencedFiles);

            // Ensure the target directories exists
            if (!System.IO.Directory.Exists(targetFolder.ToString()))
            {
                Log.Info("Create Directory: " + targetFolder.ToString());
                System.IO.Directory.CreateDirectory(targetFolder.ToString());
            }

            // Open the file to write to
            using (var fileStream = System.IO.File.Open(operationGraphFile.ToString(), System.IO.FileMode.Create, System.IO.FileAccess.Write))
                using (var writer = new System.IO.BinaryWriter(fileStream))
                {
                    // Write the build state to the file stream
                    OperationGraphWriter.Serialize(state, writer);
                }
        }