private static async Task<Document> ConvertExpressionSut(Document contextDocument,
            InvocationExpressionSyntax thatNode, CancellationToken cancellationToken)
        {
            var sut = thatNode.ArgumentList.Arguments[0].Expression;
            
            var actualCheck = NFluentAnalyzer.FindActualCheck(thatNode);

            if (sut is BinaryExpressionSyntax binaryExpressionSyntax &&
                (actualCheck.HasName("IsTrue") || actualCheck.HasName("IsFalse")))
            {
                var checkName =
                    NFluentAnalyzer.BinaryExpressionSutParser(binaryExpressionSyntax, out var realSut,
                        out var refValue);

                // can we fix this ?
                if (!string.IsNullOrEmpty(checkName))
                {
                    // use the 'sut' as 'That's argument
                    ExpressionSyntax altThat = thatNode.Update(thatNode.Expression, RoslynHelper.BuildArgumentList(realSut));

                    if (actualCheck.HasName("IsFalse"))
                    {
                        // inject 'Not'
                        altThat = SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression, altThat,
                            SyntaxFactory.IdentifierName("Not"));
                    }
                    // inject the fixed 'That'
                    var updatedCheckThat = actualCheck.ReplaceNode(thatNode, altThat);
                    // inject the proper check name
                    var altCheckNaMme = updatedCheckThat.Update(updatedCheckThat.Expression, 
                        updatedCheckThat.OperatorToken, 
                        SyntaxFactory.IdentifierName(checkName));
                    // inject the parameter
                    var newFix = ((InvocationExpressionSyntax)actualCheck.Parent).Update(altCheckNaMme, RoslynHelper.BuildArgumentList(refValue));

                    // inject the fixed check
                    var root = await contextDocument.GetSyntaxRootAsync(cancellationToken);
                    return contextDocument.WithSyntaxRoot(root.ReplaceNode(actualCheck.Parent, newFix));
                }
            }

            return contextDocument;
        }
 private static async Task<Document> ConvertEnumerableCheck(Document contextDocument, InvocationExpressionSyntax thatNode, CancellationToken cancellationToken)
 {
     var sut = thatNode.ArgumentList.Arguments[0].Expression;
     var actualCheck = NFluentAnalyzer.FindActualCheck(thatNode);
     if (sut is MemberAccessExpressionSyntax memberAccess && memberAccess.HasName("Count"))
     {
         if (actualCheck.HasName("IsEqualTo"))
         {
             // replace Check.That(sut.Count).IsEqualTo(10) by Check.That(sut).CountIs(10)
             var fixedThat = thatNode.Update(thatNode.Expression,
                 RoslynHelper.BuildArgumentList(memberAccess.Expression));
             var fixedCheck = actualCheck.Update(actualCheck.Expression.ReplaceNode(thatNode, fixedThat), 
                 actualCheck.OperatorToken, SyntaxFactory.IdentifierName("CountIs"));
             var root = await contextDocument.GetSyntaxRootAsync(cancellationToken);
             return contextDocument.WithSyntaxRoot(root.ReplaceNode(actualCheck, fixedCheck));
         }
     }
     return contextDocument;
 }
 public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
 {
     var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
     foreach (var contextDiagnostic in context.Diagnostics)
     {
         var invocationExpression = root.FindToken(contextDiagnostic.Location.SourceSpan.Start).Parent
             .AncestorsAndSelf()
             .OfType<ExpressionStatementSyntax>().First();
         var thatNode =
             NFluentAnalyzer.FindInvocationOfThat(await context.Document.GetSemanticModelAsync(context.CancellationToken),
                 invocationExpression);
         if (thatNode == null)
         {
             return;
         }
         switch (contextDiagnostic.Id)
         {
             case NFluentAnalyzer.MissingCheckId:
                 FixMissingCheck(context, thatNode, contextDiagnostic);
                 break;
             case NFluentAnalyzer.SutIsTheCheckId:
                 context.RegisterCodeFix(
                     CodeAction.Create(CodeFixResources.ExpandBinaryExpressionTitle,
                         c => ConvertExpressionSut(context.Document, thatNode, c),
                         nameof(CodeFixResources.ExpandBinaryExpressionTitle)),
                     contextDiagnostic);
                 break;
             case NFluentAnalyzer.EnumerationCheckId:
                 context.RegisterCodeFix(CodeAction.Create(CodeFixResources.SwitchToEnumerableCheck, 
                         c => ConvertEnumerableCheck(context.Document, thatNode, c), 
                         nameof(CodeFixResources.SwitchToEnumerableCheck)), 
                     contextDiagnostic);
                 break;
         }
     }
 }