private static void CommentOrUncommentSelection(
            ITextView textView,
            IEnumerable <TextChange> expectedChanges,
            IEnumerable <Span> expectedSelectedSpans,
            bool supportBlockComments,
            CommentUncommentSelectionCommandHandler.Operation operation)
        {
            var textUndoHistoryRegistry = TestExportProvider.ExportProviderWithCSharpAndVisualBasic.GetExportedValue <ITextUndoHistoryRegistry>();
            var editorOperationsFactory = TestExportProvider.ExportProviderWithCSharpAndVisualBasic.GetExportedValue <IEditorOperationsFactoryService>();
            var commandHandler          = new CommentUncommentSelectionCommandHandler(TestWaitIndicator.Default, textUndoHistoryRegistry, editorOperationsFactory);
            var service = new MockCommentUncommentService(supportBlockComments);

            var trackingSpans = new List <ITrackingSpan>();
            var textChanges   = new List <TextChange>();

            commandHandler.CollectEdits(service,
                                        textView.Selection.GetSnapshotSpansOnBuffer(textView.TextBuffer), textChanges, trackingSpans, operation);

            AssertEx.SetEqual(expectedChanges, textChanges);

            // Actually apply the edit to let the tracking spans adjust.
            using (var edit = textView.TextBuffer.CreateEdit())
            {
                textChanges.Do(tc => edit.Replace(tc.Span.ToSpan(), tc.NewText));

                edit.Apply();
            }

            if (trackingSpans.Any())
            {
                textView.SetSelection(trackingSpans.First().GetSpan(textView.TextSnapshot));
            }

            if (expectedSelectedSpans != null)
            {
                AssertEx.Equal(expectedSelectedSpans, textView.Selection.SelectedSpans.Select(snapshotSpan => snapshotSpan.Span));
            }
        }
        private static void CommentOrUncommentSelection(
            ITextView textView,
            IEnumerable<TextChange> expectedChanges,
            IEnumerable<Span> expectedSelectedSpans,
            bool supportBlockComments,
            CommentUncommentSelectionCommandHandler.Operation operation)
        {
            var textUndoHistoryRegistry = TestExportProvider.ExportProviderWithCSharpAndVisualBasic.GetExportedValue<ITextUndoHistoryRegistry>();
            var editorOperationsFactory = TestExportProvider.ExportProviderWithCSharpAndVisualBasic.GetExportedValue<IEditorOperationsFactoryService>();
            var commandHandler = new CommentUncommentSelectionCommandHandler(TestWaitIndicator.Default, textUndoHistoryRegistry, editorOperationsFactory);
            var service = new MockCommentUncommentService(supportBlockComments);

            var trackingSpans = new List<ITrackingSpan>();
            var textChanges = new List<TextChange>();

            commandHandler.CollectEdits(service,
                textView.Selection.GetSnapshotSpansOnBuffer(textView.TextBuffer), textChanges, trackingSpans, operation);

            AssertEx.SetEqual(expectedChanges, textChanges);

            // Actually apply the edit to let the tracking spans adjust.
            using (var edit = textView.TextBuffer.CreateEdit())
            {
                textChanges.Do(tc => edit.Replace(tc.Span.ToSpan(), tc.NewText));

                edit.Apply();
            }

            if (trackingSpans.Any())
            {
                textView.SetSelection(trackingSpans.First().GetSpan(textView.TextSnapshot));
            }

            if (expectedSelectedSpans != null)
            {
                AssertEx.Equal(expectedSelectedSpans, textView.Selection.SelectedSpans.Select(snapshotSpan => snapshotSpan.Span));
            }
        }