// SuspendAllFileWatchers/ResumeAllFileWatchers are commented out. They are useful if an
        // extension performs an action and then EVERYTHING is reloaded. But it is also dangerous
        // if the file watchers can be used to watch files that are not registered documents and
        // we cannot make if they are also reloaded.
        ///// <summary>
        ///// Suspends the <see cref="FileSystemWatcher"/>s for all documents.
        ///// </summary>
        ///// <seealso cref="StartFileWatcher"/>
        ///// <seealso cref="StopFileWatcher"/>
        ///// <seealso cref="SuspendFileWatcher"/>
        ///// <seealso cref="SuspendAllFileWatchers"/>
        ///// <seealso cref="ResumeFileWatcher"/>
        ///// <seealso cref="ResumeAllFileWatchers"/>
        //public void SuspendAllFileWatchers()
        //{
        //    Logger.Debug("Suspending all file watchers.");

        //    foreach (var fileWatcher in _fileWatchers)
        //        fileWatcher.Suspend();
        //}


        ///// <summary>
        ///// Resumes the <see cref="FileSystemWatcher"/>.
        ///// </summary>
        ///// <seealso cref="StopFileWatcher"/>
        ///// <seealso cref="SuspendFileWatcher"/>
        ///// <seealso cref="SuspendAllFileWatchers"/>
        ///// <seealso cref="ResumeFileWatcher"/>
        ///// <seealso cref="ResumeAllFileWatchers"/>
        //public void ResumeAllFileWatchers()
        //{
        //    Logger.Debug("Resuming all file watchers.");

        //    foreach (var fileWatcher in _fileWatchers)
        //        fileWatcher.Resume();
        //}


        private void OnFileChanged(object sender, FileSystemEventArgs eventArgs)
        {
            var fileWatcher = (FileWatcher)sender;

            Debug.Assert(sender != null);
            Debug.Assert(eventArgs.ChangeType == WatcherChangeTypes.Changed);

            var document = fileWatcher.Document;

            Logger.Debug(CultureInfo.InvariantCulture, "File watcher detected change for document \"{0}\".", document.GetName());

            // Record file change.
            var fileChangeRecord = new FileChangeRecord(document, eventArgs);

            lock (_fileChangeRecords)
            {
                if (_fileChangeRecords.Find(record => record.Document == document) == null)
                {
                    // Multiple changes of the same file are only recorded once.
                    _fileChangeRecords.Add(fileChangeRecord);
                }
            }
        }
        private void ApplyFileChange(FileChangeRecord record, ref ReloadFileChoice unmodifiedDocumentsChoice, ref ReloadFileChoice modifiedDocumentsChoice)
        {
            Debug.Assert(record.Document != null);
            Debug.Assert(record.FileSystemEventArgs != null && record.FileSystemEventArgs.ChangeType == WatcherChangeTypes.Changed);

            var  document   = record.Document;
            bool isModified = document.IsModified;
            bool reloadFile = false;

            if (!isModified && unmodifiedDocumentsChoice == ReloadFileChoice.Prompt ||
                isModified && modifiedDocumentsChoice == ReloadFileChoice.Prompt)
            {
                // Select the affected document
                ShowDocument(document);

                // Ask the user what to do.
                var reloadFileDialog = new ReloadFileViewModel
                {
                    FileName       = document.Uri.LocalPath,
                    IsFileModified = document.IsModified,
                    DisplayName    = Editor.ApplicationName,
                };
                _windowService.ShowDialog(reloadFileDialog);

                switch (reloadFileDialog.ReloadFileDialogResult)
                {
                case ReloadFileDialogResult.Yes:
                    // The user has chosen to reload the current document.
                    // Prompt her again, when another file has changed.
                    reloadFile = true;
                    if (isModified)
                    {
                        modifiedDocumentsChoice = ReloadFileChoice.Prompt;
                    }
                    else
                    {
                        unmodifiedDocumentsChoice = ReloadFileChoice.Prompt;
                    }
                    break;

                case ReloadFileDialogResult.YesToAll:
                    // The user has chosen to reload the documents for all changed files.
                    // Apply this rule to all similar files.
                    reloadFile = true;
                    if (isModified)
                    {
                        modifiedDocumentsChoice = ReloadFileChoice.ReloadAll;
                    }
                    else
                    {
                        unmodifiedDocumentsChoice = ReloadFileChoice.ReloadAll;
                    }
                    break;

                case ReloadFileDialogResult.No:
                    // The user has chosen to ignore the file change for the current document.
                    // Prompt her again, when another file has changed.
                    reloadFile = false;
                    if (isModified)
                    {
                        modifiedDocumentsChoice = ReloadFileChoice.Prompt;
                    }
                    else
                    {
                        unmodifiedDocumentsChoice = ReloadFileChoice.Prompt;
                    }
                    break;

                case ReloadFileDialogResult.NoToAll:
                    // The user has chosen to ignore the file change for the current document.
                    // Apply the same to all other files.
                    reloadFile = false;
                    if (isModified)
                    {
                        modifiedDocumentsChoice = ReloadFileChoice.IgnoreAll;
                    }
                    else
                    {
                        unmodifiedDocumentsChoice = ReloadFileChoice.IgnoreAll;
                    }
                    break;

                default:
                    throw new InvalidOperationException("Invalid value returned by ReloadFileDialog");
                }
            }
            else
            {
                // The user has already decided what to do.
                if (!document.IsModified && unmodifiedDocumentsChoice == ReloadFileChoice.ReloadAll ||
                    document.IsModified && modifiedDocumentsChoice == ReloadFileChoice.ReloadAll)
                {
                    reloadFile = true;
                }
            }

            if (reloadFile)
            {
                Logger.Info(CultureInfo.InvariantCulture, "Reloading document \"{0}\".", document.GetName());
                Reload(document, true);
                Debug.Assert(document.IsModified == false);
            }
        }