public async Task FileRemoved_DirectoryAdded(string[] deletedFiles, string[] createdDirectories, string[] expectedRemovedFiles, string[] expectedAddedDirectories, string[] expectedAddedFiles)
            {
                const string projectDirectorySubtree = @"
[a]
  [def]
    x.r
    y.r
    [z.r]
[b]
  [abc]
  z.r";

                foreach (var path in deletedFiles)
                {
                    FileInfoStubFactory.Create(_fileSystem, path);
                }
                RaiseCreated(_fileWatcher, deletedFiles);
                await _taskScheduler;

                using (_taskScheduler.Pause()) {
                    RaiseDeleted(_fileWatcher, deletedFiles);
                    DirectoryInfoStubFactory.FromIndentedString(_fileSystem, ProjectDirectory, projectDirectorySubtree);
                    RaiseCreated(_directoryWatcher, createdDirectories);

                    _taskScheduler.ScheduledTasksCount.Should().Be(1);
                }

                await _taskScheduler;

                _changeset.Should().NotBeNull()
                .And.HaveAddedFiles(expectedAddedFiles)
                .And.HaveAddedDirectories(expectedAddedDirectories)
                .And.HaveRemovedFiles(expectedRemovedFiles)
                .And.NoOtherChanges();
            }
            public async Task FileAdded_DirectoryRemoved(string[] addedFiles, string[] existingFiles, string[] deletedDirectories, string[] expectedFiles, string[] expectedDirectories)
            {
                await InjectDirectoriesIntoWatcher(_directoryWatcher, _fileSystem, deletedDirectories, _taskScheduler);

                using (_taskScheduler.Pause()) {
                    foreach (var path in addedFiles)
                    {
                        FileInfoStubFactory.Create(_fileSystem, path);
                    }

                    RaiseCreated(_fileWatcher, addedFiles);

                    foreach (var path in addedFiles)
                    {
                        FileInfoStubFactory.Delete(_fileSystem, path);
                    }

                    foreach (var path in existingFiles)
                    {
                        FileInfoStubFactory.Create(_fileSystem, path);
                    }

                    RaiseDeleted(_directoryWatcher, deletedDirectories);

                    _taskScheduler.ScheduledTasksCount.Should().Be(1);
                }

                await _taskScheduler;

                _changeset.Should().NotBeNull()
                .And.HaveAddedFiles(expectedFiles)
                .And.HaveRemovedDirectories(expectedDirectories)
                .And.NoOtherChanges();
            }
            public async Task FileAdded_ThenRemoved(string[] createdFiles, string[] deletedFiles, string[] expectedAdded, string[] expectedRemoved)
            {
                await InjectFilesIntoWatcher(_fileWatcher, _fileSystem, deletedFiles, _taskScheduler);

                using (_taskScheduler.Pause()) {
                    foreach (var path in createdFiles)
                    {
                        FileInfoStubFactory.Create(_fileSystem, path);
                        RaiseCreated(_fileWatcher, path);
                    }

                    foreach (var path in deletedFiles)
                    {
                        FileInfoStubFactory.Delete(_fileSystem, path);
                        RaiseDeleted(_fileWatcher, path);
                    }

                    _taskScheduler.ScheduledTasksCount.Should().Be(1);
                }

                await _taskScheduler;

                _changeset.Should().NotBeNull()
                .And.HaveAddedFiles(expectedAdded)
                .And.HaveRemovedFiles(expectedRemoved)
                .And.NoOtherChanges();
            }
        private static async Task InjectFilesIntoWatcher(IFileSystemWatcher fileWatcher, IFileSystem fileSystem, IEnumerable <string> fullPaths, ControlledTaskScheduler taskScheduler)
        {
            var files = fullPaths.AsList();

            foreach (var path in files)
            {
                FileInfoStubFactory.Create(fileSystem, path);
            }
            RaiseCreated(fileWatcher, files);
            await taskScheduler;

            foreach (var path in files)
            {
                FileInfoStubFactory.Delete(fileSystem, path);
            }
        }
            public async Task FileAdded(string[] addedFiles, string[] expected)
            {
                using (_taskScheduler.Pause()) {
                    foreach (var path in addedFiles)
                    {
                        FileInfoStubFactory.Create(_fileSystem, path);
                    }

                    RaiseCreated(_fileWatcher, addedFiles);
                    _taskScheduler.ScheduledTasksCount.Should().Be(1);
                }

                await _taskScheduler;

                _changeset.Should().NotBeNull()
                .And.HaveAddedFiles(expected)
                .And.NoOtherChanges();
            }
            public async Task FileWatcherError_Recovered()
            {
                var errorTask = EventTaskSources.MsBuildFileSystemWatcher.Error.Create(_fileSystemWatcher);

                using (_taskScheduler.Pause()) {
                    _fileWatcher.Error += Raise.Event <ErrorEventHandler>(_fileWatcher, new ErrorEventArgs(new InvalidOperationException()));
                }

                await _taskScheduler;

                errorTask.IsCompleted.Should().BeFalse();

                using (_taskScheduler.Pause()) {
                    FileInfoStubFactory.Create(_fileSystem, @"Z:\abc\abc.cs");
                    RaiseCreated(_fileWatcher, @"Z:\abc\abc.cs");
                }

                await _taskScheduler;

                _changeset.Should().NotBeNull()
                .And.HaveAddedFiles("abc.cs")
                .And.NoOtherChanges();
            }