private async Task <Document> FixAllAsync(
            Document document,
            ImmutableArray <Diagnostic> diagnostics,
            CancellationToken cancellationToken)
        {
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();
            var root        = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var editor    = new SyntaxEditor(root, document.Project.Solution.Workspace);
            var generator = editor.Generator;

            foreach (var diagnostic in diagnostics)
            {
                var conditionalExpression = root.FindNode(diagnostic.AdditionalLocations[0].SourceSpan, getInnermostNodeForTie: true);
                var conditionalPart       = root.FindNode(diagnostic.AdditionalLocations[1].SourceSpan);
                var whenPart = root.FindNode(diagnostic.AdditionalLocations[2].SourceSpan);

                SyntaxNode condition, whenTrue, whenFalse;
                syntaxFacts.GetPartsOfConditionalExpression(
                    conditionalExpression, out condition, out whenTrue, out whenFalse);

                editor.ReplaceNode(conditionalExpression,
                                   (c, g) => {
                    SyntaxNode currentCondition, currentWhenTrue, currentWhenFalse;
                    syntaxFacts.GetPartsOfConditionalExpression(
                        c, out currentCondition, out currentWhenTrue, out currentWhenFalse);

                    var currentWhenPartToCheck = whenPart == whenTrue ? currentWhenTrue : currentWhenFalse;

                    var match = AbstractUseNullPropagationDiagnosticAnalyzer <
                        TSyntaxKind, TExpressionSyntax, TConditionalExpressionSyntax,
                        TBinaryExpressionSyntax, TInvocationExpression, TMemberAccessExpression,
                        TConditionalAccessExpression, TElementAccessExpression> .GetWhenPartMatch(syntaxFacts, conditionalPart, currentWhenPartToCheck);
                    if (match == null)
                    {
                        return(c);
                    }

                    var newNode = CreateConditionalAccessExpression(
                        syntaxFacts, g, currentWhenPartToCheck, match, c);

                    newNode = newNode.WithTriviaFrom(c);
                    return(newNode);
                });
            }

            var newRoot = editor.GetChangedRoot();

            return(document.WithSyntaxRoot(newRoot));
        }
        private void FixConditionalExpression(
            Document document,
            SyntaxEditor editor,
            SemanticModel semanticModel,
            Diagnostic diagnostic,
            SyntaxNode conditionalExpression,
            CancellationToken cancellationToken)
        {
            var root = editor.OriginalRoot;

            var syntaxFacts = document.GetRequiredLanguageService <ISyntaxFactsService>();
            var generator   = document.GetRequiredLanguageService <SyntaxGeneratorInternal>();

            var conditionalPart = root.FindNode(diagnostic.AdditionalLocations[1].SourceSpan, getInnermostNodeForTie: true);
            var whenPart        = root.FindNode(diagnostic.AdditionalLocations[2].SourceSpan, getInnermostNodeForTie: true);

            syntaxFacts.GetPartsOfConditionalExpression(
                conditionalExpression, out var condition, out var whenTrue, out var whenFalse);
            whenTrue  = syntaxFacts.WalkDownParentheses(whenTrue);
            whenFalse = syntaxFacts.WalkDownParentheses(whenFalse);

            var whenPartIsNullable = diagnostic.Properties.ContainsKey(UseNullPropagationConstants.WhenPartIsNullable);

            editor.ReplaceNode(
                conditionalExpression,
                (conditionalExpression, _) =>
            {
                syntaxFacts.GetPartsOfConditionalExpression(
                    conditionalExpression, out var currentCondition, out var currentWhenTrue, out var currentWhenFalse);

                var currentWhenPartToCheck = whenPart == whenTrue ? currentWhenTrue : currentWhenFalse;

                var match = AbstractUseNullPropagationDiagnosticAnalyzer <
                    TSyntaxKind, TExpressionSyntax, TStatementSyntax,
                    TConditionalExpressionSyntax, TBinaryExpressionSyntax, TInvocationExpressionSyntax,
                    TConditionalAccessExpressionSyntax, TElementAccessExpressionSyntax,
                    TIfStatementSyntax, TExpressionStatementSyntax> .GetWhenPartMatch(
                    syntaxFacts, semanticModel, (TExpressionSyntax)conditionalPart, (TExpressionSyntax)currentWhenPartToCheck, cancellationToken);
                if (match == null)
                {
                    return(conditionalExpression);
                }

                var newNode = CreateConditionalAccessExpression(
                    syntaxFacts, generator, whenPartIsNullable, currentWhenPartToCheck, match) ?? conditionalExpression;

                newNode = newNode.WithTriviaFrom(conditionalExpression);
                return(newNode);
            });
        protected override Task FixAllAsync(
            Document document, ImmutableArray <Diagnostic> diagnostics,
            SyntaxEditor editor, CancellationToken cancellationToken)
        {
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();
            var generator   = editor.Generator;
            var root        = editor.OriginalRoot;

            foreach (var diagnostic in diagnostics)
            {
                var conditionalExpression = root.FindNode(diagnostic.AdditionalLocations[0].SourceSpan, getInnermostNodeForTie: true);
                var conditionalPart       = root.FindNode(diagnostic.AdditionalLocations[1].SourceSpan);
                var whenPart = root.FindNode(diagnostic.AdditionalLocations[2].SourceSpan);

                SyntaxNode condition, whenTrue, whenFalse;
                syntaxFacts.GetPartsOfConditionalExpression(
                    conditionalExpression, out condition, out whenTrue, out whenFalse);

                editor.ReplaceNode(conditionalExpression,
                                   (c, g) => {
                    SyntaxNode currentCondition, currentWhenTrue, currentWhenFalse;
                    syntaxFacts.GetPartsOfConditionalExpression(
                        c, out currentCondition, out currentWhenTrue, out currentWhenFalse);

                    var currentWhenPartToCheck = whenPart == whenTrue ? currentWhenTrue : currentWhenFalse;

                    var match = AbstractUseNullPropagationDiagnosticAnalyzer <
                        TSyntaxKind, TExpressionSyntax, TConditionalExpressionSyntax,
                        TBinaryExpressionSyntax, TInvocationExpression, TMemberAccessExpression,
                        TConditionalAccessExpression, TElementAccessExpression> .GetWhenPartMatch(syntaxFacts, conditionalPart, currentWhenPartToCheck);
                    if (match == null)
                    {
                        return(c);
                    }

                    var newNode = CreateConditionalAccessExpression(
                        syntaxFacts, g, currentWhenPartToCheck, match, c);

                    newNode = newNode.WithTriviaFrom(c);
                    return(newNode);
                });
            }

            return(SpecializedTasks.EmptyTask);
        }
        protected override async Task FixAllAsync(
            Document document, ImmutableArray <Diagnostic> diagnostics,
            SyntaxEditor editor, CancellationToken cancellationToken)
        {
            var syntaxFacts   = document.GetLanguageService <ISyntaxFactsService>();
            var semanticFacts = document.GetLanguageService <ISemanticFactsService>();
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var generator = editor.Generator;
            var root      = editor.OriginalRoot;

            foreach (var diagnostic in diagnostics)
            {
                var conditionalExpression = root.FindNode(diagnostic.AdditionalLocations[0].SourceSpan, getInnermostNodeForTie: true);
                var conditionalPart       = root.FindNode(diagnostic.AdditionalLocations[1].SourceSpan, getInnermostNodeForTie: true);
                var whenPart = root.FindNode(diagnostic.AdditionalLocations[2].SourceSpan, getInnermostNodeForTie: true);
                syntaxFacts.GetPartsOfConditionalExpression(
                    conditionalExpression, out var condition, out var whenTrue, out var whenFalse);

                var whenPartIsNullable = diagnostic.Properties.ContainsKey(UseNullPropagationConstants.WhenPartIsNullable);
                editor.ReplaceNode(conditionalExpression,
                                   (c, g) =>
                {
                    syntaxFacts.GetPartsOfConditionalExpression(
                        c, out var currentCondition, out var currentWhenTrue, out var currentWhenFalse);

                    var currentWhenPartToCheck = whenPart == whenTrue ? currentWhenTrue : currentWhenFalse;

                    var match = AbstractUseNullPropagationDiagnosticAnalyzer <
                        TSyntaxKind, TExpressionSyntax, TConditionalExpressionSyntax,
                        TBinaryExpressionSyntax, TInvocationExpression, TMemberAccessExpression,
                        TConditionalAccessExpression, TElementAccessExpression> .GetWhenPartMatch(syntaxFacts, semanticFacts, semanticModel, conditionalPart, currentWhenPartToCheck);
                    if (match == null)
                    {
                        return(c);
                    }

                    var newNode = CreateConditionalAccessExpression(
                        syntaxFacts, g, whenPartIsNullable, currentWhenPartToCheck, match, c);

                    newNode = newNode.WithTriviaFrom(c);
                    return(newNode);
                });