private void OnSelectedItemsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            DeleteFolder.RaiseCanExecuteChanged();
            var fileNodes = FileBrowser.SelectedItems.OfType <FileNode>().ToArray();

            _fileNodeService.ParallelLoadFileNodeBatch(fileNodes);
        }
Exemple #2
0
        /*** メイン ***/
        static void Main(string[] args)
        {
            DeleteFolder df = new DeleteFolder();

            //何日前のフォルダを削除するか設定
            int del_days = 1;

            //設定した日付前のフォルダを削除するメソッド
            if (df.Delete_Folder(del_days))
            {
                Console.WriteLine("{0}分以前のフォルダを完全削除しました。", (DateTime.Now + TimeSpan.FromDays(-del_days)).ToString("yyyyMMdd"));
            }

            // 時間の差をもってバッジを実行するようタイマー用意
            System.Timers.Timer timer = new System.Timers.Timer();

            // 時間の差を設定
            timer.Interval = 1 * 60 * 1000; //30分

            Timer_action action = new Timer_action();

            //イベントハンドラー設定
            timer.Elapsed += new ElapsedEventHandler(action.timer_Elapsed);
            timer.Start();

            //終了する時に使う構文
            Console.WriteLine("Press Enter to exit");
            Console.ReadLine();
        }
        public FoldersAndLabelsPage DeleteThirdFolder()
        {
            FolderOptions.Click();

            WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(3));

            wait.Until(ExpectedConditions.ElementToBeClickable(DeleteFolderWait));
            DeleteFolder.Click();
            ConfirmDeletionOfFolderButton.Click();
            return(this);
        }
Exemple #4
0
        public void Dispose()
        {
            // Clearing all of these ensures that the transient APIs
            // can't be called outside of the appropriate scope.

            #region dispose-dispatcher service-apis
            _GetNuGetExePath             = null;
            _GetNuGetDllPath             = null;
            _DownloadFile                = null;
            _AddPinnedItemToTaskbar      = null;
            _RemovePinnedItemFromTaskbar = null;
            _CreateShortcutLink          = null;
            _UnzipFileIncremental        = null;
            _UnzipFile                 = null;
            _AddFileAssociation        = null;
            _RemoveFileAssociation     = null;
            _AddExplorerMenuItem       = null;
            _RemoveExplorerMenuItem    = null;
            _SetEnvironmentVariable    = null;
            _RemoveEnvironmentVariable = null;
            _AddFolderToPath           = null;
            _RemoveFolderFromPath      = null;
            _InstallMSI                = null;
            _RemoveMSI                 = null;
            _StartProcess              = null;
            _InstallVSIX               = null;
            _UninstallVSIX             = null;
            _InstallPowershellScript   = null;
            _UninstallPowershellScript = null;
            _SearchForExecutable       = null;
            _GetUserBinFolder          = null;
            _GetSystemBinFolder        = null;
            _CopyFile                = null;
            _CopyFolder              = null;
            _Delete                  = null;
            _DeleteFolder            = null;
            _CreateFolder            = null;
            _DeleteFile              = null;
            _BeginTransaction        = null;
            _AbortTransaction        = null;
            _EndTransaction          = null;
            _GenerateUninstallScript = null;
            _GetKnownFolder          = null;
            _IsElevated              = null;
            #endregion

            #region dispose-dispatcher core-apis
            _Warning          = null;
            _Message          = null;
            _Error            = null;
            _Debug            = null;
            _Verbose          = null;
            _ExceptionThrown  = null;
            _Progress         = null;
            _ProgressComplete = null;
            _GetHostDelegate  = null;
            _IsCancelled      = null;
            #endregion

            #region dispose-dispatcher request-apis
            _OkToContinue                       = null;
            _YieldPackage                       = null;
            _YieldPackageDetails                = null;
            _YieldPackageSwidtag                = null;
            _YieldSource                        = null;
            _YieldMetadataDefinition            = null;
            _YieldInstallationOptionsDefinition = null;
            #endregion

            #region dispose-dispatcher host-apis
            _GetMetadataKeys             = null;
            _GetMetadataValues           = null;
            _GetInstallationOptionKeys   = null;
            _GetInstallationOptionValues = null;
            _PackageSources   = null;
            _GetConfiguration = null;
            _ShouldContinueWithUntrustedPackageSource = null;
            _ShouldProcessPackageInstall                = null;
            _ShouldProcessPackageUninstall              = null;
            _ShouldContinueAfterPackageInstallFailure   = null;
            _ShouldContinueAfterPackageUninstallFailure = null;
            _ShouldContinueRunningInstallScript         = null;
            _ShouldContinueRunningUninstallScript       = null;
            _AskPermission = null;
            _WhatIf        = null;
            #endregion

            #region dispose-dispatcher protocol-apis
            _ProtocolGetNames        = null;
            _ProtocolIsValidSource   = null;
            _ProtocolGetItemMetadata = null;
            _ProtocolDownloadItem    = null;
            _ProtocolUnpackItem      = null;
            _InstallItem             = null;
            #endregion

            _callback = null;
        }
Exemple #5
0
 public void DeleteFolder(string folder)
 {
     CheckDisposed();
     (_DeleteFolder ?? (_DeleteFolder = (_callback.Resolve <DeleteFolder>() ?? ((pfolder) => { }))))(folder);
 }
Exemple #6
0
 public ClientHandler(IExecuteCommand exec, DeleteFolder handl)
 {
     this.handle = handl;
     this.exec   = exec;
 }
Exemple #7
0
        public static SetupTask CreateFrom(XElement taskElement)
        {
            SetupTask result;

            switch (taskElement.Name.LocalName)
            {
            case "Group":
                result = new Composite(taskElement);
                break;

            case "ExtractArchive":
                result = new ExtractArchive(taskElement);
                break;

            case "TweakINI":
                result = new TweakINI(taskElement);
                break;

            case "CopyFile":
                result = new CopyFile(taskElement);
                break;

            case "Embedded":
                result = new Embedded(taskElement);
                break;

            case "Clean":
                result = new Clean(taskElement);
                break;

            case "CreateEmptyFolder":
                result = new CreateEmptyFolder(taskElement);
                break;

            case "RunProcess":
                result = new RunProcess(taskElement);
                break;

            case "DeleteFolder":
                result = new DeleteFolder(taskElement);
                break;

            case "DeleteFile":
                result = new DeleteFile(taskElement);
                break;

            case "MoveFolder":
                result = new MoveFolder(taskElement);
                break;

            case "EditFile":
                result = new EditFile(taskElement);
                break;

            case "Dummy":
                result = new Composite();
                break;

            default:
                throw new NotSupportedException("Task type " + taskElement.Name.LocalName + " is not supported.");
            }

            result.xml = taskElement.ToString();
            result.Id  = taskElement.Attribute("Id")?.Value ?? Guid.NewGuid().ToString();

            // this feels clunky, but that's fine I guess...
            result.WaitFor = result.WaitFor.Union(Program.Tokenize(taskElement.Attribute("WaitFor")?.Value)).ToImmutableArray();
            return(result);
        }
Exemple #8
0
        private ActionBase ParseObjectAction(JObject node, ActionType action_type)
        {
            switch (action_type)
            {
            case ActionType.ControlFlow:
                var condition = (node["condition"].ToString());

                if (condition.Equals("dialog"))
                {
                    return(ParseDialogControlFlow(node));
                }

                return(null);

            case ActionType.Execute:

                string filename         = mroot.substitue_enviro_vars(node["filename"].ToString());
                string paramxs          = node.ContainsKey("params") ? mroot.substitue_enviro_vars(node["params"].ToString()) : "";
                bool   onlyIfnotRunning = node.ContainsKey("onlyIfNotRunning") ? node["params"].Value <bool>() : true;

                ExecuteProcess executeAction = new ExecuteProcess();
                executeAction.FileName         = filename;
                executeAction.Params           = paramxs;
                executeAction.OnlyIfNotRunning = onlyIfnotRunning;

                return(executeAction);


            case ActionType.Wait:
                int waittime = (node["duration_ms"].Value <Int32>());

                WaitAction wait = new WaitAction();
                wait.Milliseconds = waittime;
                return(wait);

            case ActionType.ShowDialog:

                ShowDialog showDialog = new ShowDialog();
                showDialog.Message = mroot.substitue_enviro_vars(node["message"].ToString());
                if (node.ContainsKey("messagetype"))
                {
                    showDialog.MessageType = (ShowDialog.Type)Enum.Parse(typeof(ShowDialog.Type), node["messagetype"].ToString(), true);
                }
                return(showDialog);

            case ActionType.CopyFolder:

                string source       = mroot.substitue_enviro_vars(node["source"].ToString());
                string destination  = mroot.substitue_enviro_vars(node["destination"].ToString());
                string file_pattern = node.ContainsKey("desc") ? node["copy_filepattern"].ToString() : null;
                string dir_pattern  = node.ContainsKey("desc") ? node["copy_dirpattern"].ToString() : null;

                CopyFolder copyFolder = new CopyFolder();
                copyFolder.Source          = source ?? copyFolder.Source;
                copyFolder.Destination     = destination ?? copyFolder.Destination;
                copyFolder.CopyFilePattern = file_pattern ?? copyFolder.CopyFilePattern;
                copyFolder.CopyDirPattern  = dir_pattern ?? copyFolder.CopyDirPattern;

                return(copyFolder);

            case ActionType.CopyFile:

                source      = mroot.substitue_enviro_vars(node["source"].ToString());
                destination = mroot.substitue_enviro_vars(node["destination"].ToString());

                CopyFile copyFile = new CopyFile();
                copyFile.Source      = source;
                copyFile.Destination = destination;
                return(copyFile);

            case ActionType.DeleteFile:
            {
                string sourceFile = mroot.substitue_enviro_vars(node["source"].ToString());

                DeleteFile delteFiles = new DeleteFile();
                delteFiles.SourceFile = sourceFile;
                return(delteFiles);
            }

            case ActionType.DeleteFiles:
            {
                string sourceFolder     = mroot.substitue_enviro_vars(node["source"].ToString());
                string delete_pattern   = node.ContainsKey("pattern") ? node["pattern"].ToString() : "(.)";
                bool   recursive_delete = node.ContainsKey("recursive") ? node["recursive"].Value <bool>() : false;

                DeleteFiles delteFiles = new DeleteFiles();
                delteFiles.SourceFolder    = sourceFolder;
                delteFiles.DeletePattern   = delete_pattern;
                delteFiles.RecursiveDelete = recursive_delete;
                return(delteFiles);
            }

            case ActionType.DeleteFolder:
            {
                string dirPath = mroot.substitue_enviro_vars(node["source"].ToString());

                DeleteFolder deleteFolder = new DeleteFolder();
                deleteFolder.FolderPath = dirPath;
                return(deleteFolder);
            }

            case ActionType.DeleteFolders:
            {
                string sourceFolder   = mroot.substitue_enviro_vars(node["source"].ToString());
                string delete_pattern = node.ContainsKey("pattern") ? node["pattern"].ToString() : "(.)";

                DeleteFolders deleteFolders = new DeleteFolders();
                deleteFolders.SourceFolder  = sourceFolder;
                deleteFolders.DeletePattern = delete_pattern;
                return(deleteFolders);
            }

            case ActionType.ZipFolder:
            {
                string sourceFolder        = mroot.substitue_enviro_vars(node["source"].ToString());
                string zipfile_destination = mroot.substitue_enviro_vars(node["zipfile"].ToString());

                ZipFolder zipFolder = new ZipFolder();
                zipFolder.SourceFolder   = sourceFolder;
                zipFolder.DestinationZip = zipfile_destination;
                return(zipFolder);
            }
            }

            return(null);
        }
Exemple #9
0
        private ActionBase ParseObjectAction(JProperty node, ActionType action_type)
        {
            switch (action_type)
            {
            case ActionType.Execute:

                string filename = mroot.substitue_enviro_vars(node.Value.ToString());

                ExecuteProcess executeAction = new ExecuteProcess();
                executeAction.FileName         = filename;
                executeAction.Params           = "";
                executeAction.OnlyIfNotRunning = true;

                return(executeAction);

            case ActionType.Wait:
                int waittime = Convert.ToInt32((node.Value.ToString()));

                WaitAction wait = new WaitAction();
                wait.Milliseconds = waittime;
                return(wait);

            case ActionType.ShowDialog:

                ShowDialog showDialog = new ShowDialog();
                showDialog.Message = mroot.substitue_enviro_vars(node.Value.ToString());
                return(showDialog);

            case ActionType.CopyFolder:

                throw new NotSupportedException("Simple CopyFolder is not allowed");

            case ActionType.CopyFile:

                throw new NotSupportedException("Simple CopyFile is not allowed");

            case ActionType.DeleteFile:
            {
                string sourceFile = mroot.substitue_enviro_vars(node.Value.ToString());

                DeleteFile delteFiles = new DeleteFile();
                delteFiles.SourceFile = sourceFile;
                return(delteFiles);
            }

            case ActionType.DeleteFiles:
            {
                string sourceFolder     = mroot.substitue_enviro_vars(node.Value.ToString());
                string delete_pattern   = "(.)";
                bool   recursive_delete = false;

                DeleteFiles delteFiles = new DeleteFiles();
                delteFiles.SourceFolder    = sourceFolder;
                delteFiles.DeletePattern   = delete_pattern;
                delteFiles.RecursiveDelete = recursive_delete;
                return(delteFiles);
            }

            case ActionType.DeleteFolder:
            {
                string dirPath = mroot.substitue_enviro_vars(node.Value.ToString());

                DeleteFolder deleteFolder = new DeleteFolder();
                deleteFolder.FolderPath = dirPath;
                return(deleteFolder);
            }

            case ActionType.DeleteFolders:
            {
                string sourceFolder   = mroot.substitue_enviro_vars(node.Value.ToString());
                string delete_pattern = "(.)";

                DeleteFolders deleteFolders = new DeleteFolders();
                deleteFolders.SourceFolder  = sourceFolder;
                deleteFolders.DeletePattern = delete_pattern;
                return(deleteFolders);
            }

            case ActionType.ZipFolder:

                throw new NotSupportedException("Simple ZipFolder is not allowed");
            }

            return(null);
        }
        // NOTE: The specific task data (ExecuteDeviceCommandAsyncTaskData.Data) must be a Tuple<MenuLayout, bool, bool>.
        // The first Boolean value indicates whether the operation should attempt to force the removal of menu position data.
        // The second Boolean value indicates whether the operation should update the root file's names (device name, owner).
        private static void SyncHostToDevice(AsyncTaskData taskData)
        {
            var data   = (ExecuteDeviceCommandAsyncTaskData)taskData;
            var device = data.Device;

            data.Task.UpdateTaskProgress(0, Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ComputingChangesProgress);
            var currentDirtyFlags = GetDirtyFlags.Instance.Execute <LfsDirtyFlags>(device.Port, data);
            var deviceFileSystem  = DownloadFileSystemTables.Instance.Execute <FileSystem>(device.Port, data);

            deviceFileSystem.Status = currentDirtyFlags;
            if (data.AcceptCancelIfRequested())
            {
                return;
            }

            var hostData              = (Tuple <MenuLayout, bool, bool>)data.Data;
            var hostFileSystem        = hostData.Item1.FileSystem;
            var resetSaveMenuPosition = hostData.Item2;

            if (resetSaveMenuPosition)
            {
                hostFileSystem.ForceRemovalOfMenuPositionData(deviceFileSystem);
            }
            hostFileSystem.SuppressRootFileNameDifferences(device);
            hostFileSystem.PopulateSaveDataForksFromDevice(deviceFileSystem);

            // The first pass gathers all differences, including errors.
            var allDifferencesWithErrors = hostFileSystem.CompareTo(deviceFileSystem, device, true);

#if USE_SMART_COPY
            // Now, use a clone of the original file system to compute the actual work to do, and use the failures for a post-op error report.
            var hostFileSystemWorkingCopy = hostFileSystem.Clone();

            var ignoreRootFileNames = !hostData.Item3;
            if (ignoreRootFileNames)
            {
                hostFileSystemWorkingCopy.Files[GlobalFileTable.RootDirectoryFileNumber].ShortName = deviceFileSystem.Files[GlobalFileTable.RootDirectoryFileNumber].ShortName;
                hostFileSystemWorkingCopy.Files[GlobalFileTable.RootDirectoryFileNumber].LongName  = deviceFileSystem.Files[GlobalFileTable.RootDirectoryFileNumber].LongName;
            }

            var partialErrors  = hostFileSystemWorkingCopy.CleanUpInvalidEntries(deviceFileSystem, allDifferencesWithErrors, FileSystemHelpers.ShouldRemoveInvalidEntry, ShouldIncludeError);
            var allDifferences = hostFileSystemWorkingCopy.CompareTo(deviceFileSystem, device, true);
#else
            // This will try to copy all ROMs, even incompatible ones, and should eventually be removed.
            var hostFileSystemWorkingCopy = hostFileSystem;
            var partialErrors             = allDifferencesWithErrors.GetAllFailures(ShouldIncludeError);
            var allDifferences            = allDifferencesWithErrors;
#endif // USE_SMART_COPY

            var succeeded    = true;
            var phaseNumber  = 0;
            var updateString = string.Empty;

            // Run any delete operations...
            var total       = allDifferences.DirectoryDifferences.ToDelete.Count + allDifferences.FileDifferences.ToDelete.Count + allDifferences.ForkDifferences.ToDelete.Count + allDifferences.ForkDifferences.ToUpdate.Count;
            var numComplete = 0;
            if (data.AcceptCancelIfRequested())
            {
                return;
            }
            if (total > 0)
            {
                ++phaseNumber;

                if (!data.CancelRequsted && succeeded && allDifferences.DirectoryDifferences.ToDelete.Any())
                {
                    var deleteOpData = new DeleteOperationData(data, LfsEntityType.Directory)
                    {
                        Factory              = (gdn) => DeleteFolder.Create((byte)(uint)gdn[0]),
                        UpdateTitleFormat    = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ProgressTitleFormat,
                        UpdateTitleInfo      = Resources.Strings.LfsOperation_Remove,
                        UpdateProgressFormat = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_DeletingItemProgressFormat,
                        UpdateProgressInfo   = Resources.Strings.DirectoriesInSentence,
                        Phase = phaseNumber, Total = total, Current = numComplete
                    };
                    currentDirtyFlags |= DeleteEntries(allDifferences.DirectoryDifferences.ToDelete, deleteOpData, currentDirtyFlags, deviceFileSystem);
                    numComplete        = deleteOpData.Current;
                    succeeded          = data.Succeeded;
                }

                if (!data.CancelRequsted && succeeded && allDifferences.FileDifferences.ToDelete.Any())
                {
                    var deleteOpData = new DeleteOperationData(data, LfsEntityType.File)
                    {
                        Factory              = (gfn) => DeleteFile.Create((ushort)(uint)gfn[0]),
                        UpdateTitleFormat    = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ProgressTitleFormat,
                        UpdateTitleInfo      = Resources.Strings.LfsOperation_Remove,
                        UpdateProgressFormat = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_DeletingItemProgressFormat,
                        UpdateProgressInfo   = Resources.Strings.FilesInSentence,
                        Phase = phaseNumber, Total = total, Current = numComplete
                    };
                    currentDirtyFlags |= DeleteEntries(allDifferences.FileDifferences.ToDelete, deleteOpData, currentDirtyFlags, deviceFileSystem);
                    numComplete        = deleteOpData.Current;
                    succeeded          = data.Succeeded;
                }

                if (!data.CancelRequsted && succeeded && (allDifferences.ForkDifferences.ToDelete.Any() || allDifferences.ForkDifferences.ToUpdate.Any()))
                {
                    var deleteOpData = new DeleteOperationData(data, LfsEntityType.Fork)
                    {
                        Factory              = (gkn) => DeleteFork.Create((ushort)(uint)gkn[0]),
                        UpdateTitleFormat    = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ProgressTitleFormat,
                        UpdateTitleInfo      = Resources.Strings.LfsOperation_Remove,
                        UpdateProgressFormat = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_DeletingItemProgressFormat,
                        UpdateProgressInfo   = Resources.Strings.DeviceMultistageCommand_RemovingFileContents,
                        Phase = phaseNumber, Total = total, Current = numComplete
                    };
                    var forks = allDifferences.ForkDifferences.ToDelete.ToList();
                    var updatedForksToTreatAsDeletions = allDifferences.ForkDifferences.ToUpdate.Select(f => (uint)f.GlobalForkNumber).Where(f => !allDifferences.ForkDifferences.FailedOperations.Any(o => (o.Value.GlobalFileSystemNumber == f) && FileSystemHelpers.IsMissingForkError(o.Value)));
                    forks.AddRange(updatedForksToTreatAsDeletions);
                    currentDirtyFlags |= DeleteEntries(forks, deleteOpData, currentDirtyFlags, deviceFileSystem);
                    numComplete        = deleteOpData.Current;
                    succeeded          = data.Succeeded;
                }
            }

            if (data.AcceptCancelIfRequested())
            {
                return;
            }

            data.CurrentlyExecutingCommand = ProtocolCommandId.UnknownCommand;
            data.FailureMessage            = Resources.Strings.SyncHostToDeviceCommand_GatherUpdatesFailedMessage;
            var updateOperations = hostFileSystemWorkingCopy.GatherAllUpdates(allDifferences, device.UniqueId);
            if (updateOperations.Any())
            {
                do
                {
                    if (data.AcceptCancelIfRequested())
                    {
                        break;
                    }
                    LfsUpdateOperation operation = null;
                    data.FailureMessage = Resources.Strings.SyncHostToDevice_FetchUpdateOperationFailedMessage;
                    updateOperations    = updateOperations.FetchUpdateOperation(out operation);
                    if (data.AcceptCancelIfRequested())
                    {
                        break;
                    }

                    ++phaseNumber;
                    numComplete = 0;
                    total       = operation.Forks.Count + operation.Files.Count + operation.Directories.Count;
                    foreach (var failure in operation.Failures)
                    {
                        partialErrors[failure.Description] = failure.Exception;
                    }

                    // Load forks.
                    var address = 0u;
                    if (!data.CancelRequsted && succeeded && operation.Forks.Any())
                    {
                        data.FailureMessage = null;
                        var uploadOpData = new UploadDataOperationData(data, address)
                        {
                            TargetType           = LfsEntityType.Fork,
                            Factory              = (upl) => UploadDataBlockToRam.Create((uint)upl[0], (ByteSerializer)upl[1], (uint)upl[2]),
                            GetSerializer        = FileSystemHelpers.ToForkByteSerializer,
                            ShouldUpdateProgress = (k) => true,
                            UpdateTitleFormat    = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ProgressTitleFormat,
                            UpdateTitleInfo      = operation.ProgressTitle,
                            UpdateProgressFormat = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_TransferToRamProgressFormat,
                            Phase = phaseNumber, Total = total, Current = numComplete
                        };
                        address     = UploadEntries(operation.FileSystem.Forks, operation.Forks, uploadOpData);
                        numComplete = uploadOpData.Current;
                        succeeded   = data.Succeeded;
                    }

                    // Load GFT update.
                    if (!data.CancelRequsted && succeeded && operation.Files.Any())
                    {
                        data.FailureMessage = null;
                        var fileRange = operation.GfnRange;
                        var files     = Enumerable.Range(fileRange.Minimum, (fileRange.Maximum - fileRange.Minimum) + 1); // slower than a loop, but who cares?

                        var uploadOpData = new UploadDataOperationData(data, address)
                        {
                            TargetType           = LfsEntityType.File,
                            Factory              = (upl) => UploadDataBlockToRam.Create((uint)upl[0], (ByteSerializer)upl[1], (uint)upl[2]),
                            GetSerializer        = FileSystemHelpers.ToFileByteSerializer,
                            ShouldUpdateProgress = (f) => (f != null) && operation.Files.Contains(((ILfsFileInfo)f).GlobalFileNumber),
                            UpdateTitleFormat    = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ProgressTitleFormat,
                            UpdateTitleInfo      = operation.ProgressTitle,
                            UpdateProgressFormat = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_TransferToRamProgressFormat,
                            Phase   = phaseNumber,
                            Total   = total,
                            Current = numComplete
                        };

                        // THIS COULD BE DONE WITH ONE LARGE BLOCK INSTEAD OF MANY SMALLER ONES
                        address     = UploadEntries(operation.FileSystem.Files, files, uploadOpData);
                        numComplete = uploadOpData.Current;
                        succeeded   = data.Succeeded;
                    }

                    // Load GDT update.
                    if (!data.CancelRequsted && succeeded && operation.Directories.Any())
                    {
                        data.FailureMessage = null;
                        var directoryRange = operation.GdnRange;
                        var directories    = Enumerable.Range(directoryRange.Minimum, (directoryRange.Maximum - directoryRange.Minimum) + 1); // slower than a loop, but who cares?

                        var uploadOpData = new UploadDataOperationData(data, address)
                        {
                            TargetType           = LfsEntityType.Directory,
                            Factory              = (upl) => UploadDataBlockToRam.Create((uint)upl[0], (ByteSerializer)upl[1], (uint)upl[2]),
                            GetSerializer        = FileSystemHelpers.ToDirectoryByteSerializer,
                            ShouldUpdateProgress = (d) => (d != null) && operation.Files.Contains(((IDirectory)d).GlobalDirectoryNumber),
                            UpdateTitleFormat    = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ProgressTitleFormat,
                            UpdateTitleInfo      = operation.ProgressTitle,
                            UpdateProgressFormat = Resources.Strings.DeviceMultistageCommand_UpdatingFiles_TransferToRamProgressFormat,
                            Phase   = phaseNumber,
                            Total   = total,
                            Current = numComplete
                        };

                        // THIS COULD BE DONE WITH ONE LARGE BLOCK INSTEAD OF MANY SMALLER ONES
                        address     = UploadEntries(operation.FileSystem.Directories, directories, uploadOpData);
                        numComplete = uploadOpData.Current;
                        succeeded   = data.Succeeded;
                    }
                    if (data.AcceptCancelIfRequested())
                    {
                        break;
                    }

                    // Everything is in RAM now, so execute commands.
                    address     = 0; // All the data was initially loaded at location zero.
                    numComplete = 0;
                    total       = operation.Forks.Count;
                    if (operation.Files.Count > 0)
                    {
                        ++total;
                    }
                    if (operation.Directories.Count > 0)
                    {
                        ++total;
                    }

                    // Create forks.
                    if (!data.CancelRequsted && succeeded && operation.Forks.Any())
                    {
                        data.FailureMessage = null;
                        var numCreated  = 0;
                        var numToCreate = operation.Forks.Count;
                        foreach (var gkn in operation.Forks)
                        {
                            if (data.AcceptCancelIfRequested())
                            {
                                break;
                            }
                            address = address.Align();
                            var fork = operation.FileSystem.Forks[gkn];
                            updateString = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.DeviceMultistageCommand_UpdatingFiles_ProgressTitleFormat, operation.ProgressTitle, ++numComplete, total, phaseNumber);
                            data.Task.UpdateTaskTitle(updateString);
                            updateString = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.DeviceMultistageCommand_UpdatingFiles_CreatingItemProgressFormat, fork.Name, ++numCreated, numToCreate);
                            data.Task.UpdateTaskProgress((double)numCreated / numToCreate, updateString);
                            currentDirtyFlags |= currentDirtyFlags.UpdateFileSystemDirtyState(deviceFileSystem, data, gkn, LfsOperations.Add, LfsEntityType.Fork);
                            CreateForkFromRam.Create(address, fork).Execute(device.Port, data, out succeeded);
                            address += (uint)fork.SerializeByteCount;
                        }
                        address = address.Align();
                    }

                    // Update GFT.
                    if (!data.CancelRequsted && succeeded && operation.Files.Any())
                    {
                        data.FailureMessage = null;
                        if (data.AcceptCancelIfRequested())
                        {
                            break;
                        }
                        var gftRange = operation.GfnRange;
                        if (operation.Files.Count == 1)
                        {
                            updateString = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.DeviceMultistageCommand_UpdatingFileSystemTablesOneEntry_ProgressTitleFormat, Resources.Strings.File, gftRange.Minimum, phaseNumber);
                        }
                        else
                        {
                            updateString = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.DeviceMultistageCommand_UpdatingFileSystemTables_ProgressTitleFormat, Resources.Strings.File, gftRange.Minimum, gftRange.Maximum, phaseNumber);
                        }
                        data.Task.UpdateTaskTitle(updateString);
                        data.Task.UpdateTaskProgress((double)(++numComplete) / total, Resources.Strings.DeviceMultistageCommand_UpdatingGlobalFilesTable);
                        currentDirtyFlags |= currentDirtyFlags.UpdateFileSystemDirtyState(deviceFileSystem, data, gftRange.Minimum, LfsOperations.Update, LfsEntityType.File);
                        UpdateGlobalFileTable.Create(address, gftRange).Execute(device.Port, data, out succeeded);
                        address += (uint)(gftRange.Maximum - gftRange.Minimum + 1) * LfsFileInfo.FlatSizeInBytes;
                    }

                    // Update GDT.
                    if (!data.CancelRequsted && succeeded && operation.Directories.Any())
                    {
                        data.FailureMessage = null;
                        if (data.AcceptCancelIfRequested())
                        {
                            break;
                        }
                        var gdtRange = operation.GdnRange;
                        if (operation.Directories.Count == 1)
                        {
                            updateString = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.DeviceMultistageCommand_UpdatingFileSystemTablesOneEntry_ProgressTitleFormat, Resources.Strings.Directory, gdtRange.Minimum, phaseNumber);
                        }
                        else
                        {
                            updateString = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.Strings.DeviceMultistageCommand_UpdatingFileSystemTables_ProgressTitleFormat, Resources.Strings.Directory, gdtRange.Minimum, gdtRange.Maximum, phaseNumber);
                        }
                        data.Task.UpdateTaskTitle(updateString);
                        data.Task.UpdateTaskProgress((double)(++numComplete) / total, Resources.Strings.DeviceMultistageCommand_UpdatingGlobalDirectoriesTable);
                        currentDirtyFlags |= currentDirtyFlags.UpdateFileSystemDirtyState(deviceFileSystem, data, gdtRange.Minimum, LfsOperations.Update, LfsEntityType.Directory);
                        UpdateGlobalDirectoryTable.Create(address, gdtRange).Execute(device.Port, data, out succeeded);
                        address += (uint)(gdtRange.Maximum - gdtRange.Minimum + 1) * Directory.FlatSizeInBytes;
                    }
                }while (!data.CancelRequsted && succeeded && updateOperations.Any());
            }

            if (!data.CancelRequsted && data.Succeeded)
            {
                SetDirtyFlags.Create(LfsDirtyFlags.None).Execute(device.Port, data, out succeeded);
                deviceFileSystem.Status = LfsDirtyFlags.None;
            }

            if (!data.CancelRequsted && data.Succeeded)
            {
                var updatedFileSystem = DownloadFileSystemTables.Instance.Execute(device.Port, data, out succeeded) as FileSystem;
#if USE_SMART_COPY
                partialErrors = allDifferences.CombineAllFailures(partialErrors, ShouldIncludeError);
#endif // USE_SMART_COPY
                data.Result = new Tuple <FileSystem, IDictionary <string, FailedOperationException> >(updatedFileSystem, partialErrors);
            }
        }