private static async Task <Document> BatchPragmaFixesAsync(
                AbstractSuppressionCodeFixProvider suppressionFixProvider,
                Document document,
                ImmutableArray <IPragmaBasedCodeAction> pragmaActions,
                ImmutableArray <Diagnostic> diagnostics,
                CancellationToken cancellationToken)
            {
                // We apply all the pragma suppression fixes sequentially.
                // At every application, we track the updated locations for remaining diagnostics in the document.
                var currentDiagnosticSpans = new Dictionary <Diagnostic, TextSpan>();

                foreach (var diagnostic in diagnostics)
                {
                    currentDiagnosticSpans.Add(diagnostic, diagnostic.Location.SourceSpan);
                }

                var currentDocument = document;

                for (var i = 0; i < pragmaActions.Length; i++)
                {
                    var originalpragmaAction = pragmaActions[i];
                    var diagnostic           = diagnostics[i];
                    // Get the diagnostic span for the diagnostic in latest document snapshot.
                    if (!currentDiagnosticSpans.TryGetValue(diagnostic, out var currentDiagnosticSpan))
                    {
                        // Diagnostic whose location conflicts with a prior fix.
                        continue;
                    }

                    // Compute and apply pragma suppression fix.
                    var currentTree = await currentDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                    var currentLocation = Location.Create(currentTree, currentDiagnosticSpan);
                    diagnostic = Diagnostic.Create(
                        id: diagnostic.Id,
                        category: diagnostic.Descriptor.Category,
                        message: diagnostic.GetMessage(),
                        severity: diagnostic.Severity,
                        defaultSeverity: diagnostic.DefaultSeverity,
                        isEnabledByDefault: diagnostic.Descriptor.IsEnabledByDefault,
                        warningLevel: diagnostic.WarningLevel,
                        title: diagnostic.Descriptor.Title,
                        description: diagnostic.Descriptor.Description,
                        helpLink: diagnostic.Descriptor.HelpLinkUri,
                        location: currentLocation,
                        additionalLocations: diagnostic.AdditionalLocations,
                        customTags: diagnostic.Descriptor.CustomTags,
                        properties: diagnostic.Properties,
                        isSuppressed: diagnostic.IsSuppressed);

                    var newSuppressionFixes = await suppressionFixProvider.GetFixesAsync(currentDocument, currentDiagnosticSpan, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);

                    var newSuppressionFix = newSuppressionFixes.SingleOrDefault();
                    if (newSuppressionFix != null)
                    {
                        var newPragmaAction = newSuppressionFix.Action as IPragmaBasedCodeAction ??
                                              newSuppressionFix.Action.NestedCodeActions.OfType <IPragmaBasedCodeAction>().SingleOrDefault();
                        if (newPragmaAction != null)
                        {
                            // Get the text changes with pragma suppression add/removals.
                            // Note: We do it one token at a time to ensure we get single text change in the new document, otherwise UpdateDiagnosticSpans won't function as expected.
                            // Update the diagnostics spans based on the text changes.
                            var startTokenChanges = await GetTextChangesAsync(newPragmaAction, currentDocument,
                                                                              includeStartTokenChange : true, includeEndTokenChange : false, cancellationToken : cancellationToken).ConfigureAwait(false);

                            var endTokenChanges = await GetTextChangesAsync(newPragmaAction, currentDocument,
                                                                            includeStartTokenChange : false, includeEndTokenChange : true, cancellationToken : cancellationToken).ConfigureAwait(false);

                            var currentText = await currentDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

                            var orderedChanges = startTokenChanges.Concat(endTokenChanges).OrderBy(change => change.Span).Distinct();
                            var newText        = currentText.WithChanges(orderedChanges);
                            currentDocument = currentDocument.WithText(newText);

                            // Update the diagnostics spans based on the text changes.
                            UpdateDiagnosticSpans(diagnostics, currentDiagnosticSpans, orderedChanges);
                        }
                    }
                }

                return(currentDocument);
            }