private static bool IsIsKindMethod(
     ExpressionSyntax expression,
     SemanticModel semanticModel,
     CancellationToken cancellationToken)
 {
     return expression is IdentifierNameSyntax identifierName
         && string.Equals(identifierName.Identifier.ValueText, "IsKind", StringComparison.Ordinal)
         && CSharpSymbolUtility.IsIsKindExtensionMethod(expression, semanticModel, cancellationToken);
 }
        private static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context)
        {
            var invocationExpression = (InvocationExpressionSyntax)context.Node;

            if (invocationExpression.ContainsDiagnostics)
            {
                return;
            }

            SimpleMemberInvocationExpressionInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocationExpression);

            if (!invocationInfo.Success)
            {
                return;
            }

            ISymbol symbol = null;

            string methodName = invocationInfo.NameText;

            switch (invocationInfo.Arguments.Count)
            {
            case 0:
            {
                switch (methodName)
                {
                case "First":
                {
                    if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseElementAccess))
                    {
                        UseElementAccessInsteadOfCallingFirst();
                    }

                    break;
                }
                }

                break;
            }

            case 1:
            {
                switch (methodName)
                {
                case "ElementAt":
                {
                    if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseElementAccess))
                    {
                        UseElementAccessInsteadOfCallingElementAt();
                    }

                    break;
                }

                case "IsKind":
                {
                    if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UnnecessaryNullCheck))
                    {
                        AnalyzeUnnecessaryNullCheck();
                    }

                    break;
                }
                }

                break;
            }
            }

            if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseReturnValue) &&
                invocationExpression.IsParentKind(SyntaxKind.ExpressionStatement))
            {
                UseReturnValue();
            }

            void AnalyzeUnnecessaryNullCheck()
            {
                ExpressionSyntax expression = invocationInfo.InvocationExpression.WalkUpParentheses();

                SyntaxNode parent = expression.Parent;

                if (!parent.IsKind(SyntaxKind.LogicalAndExpression))
                {
                    return;
                }

                var binaryExpression = (BinaryExpressionSyntax)parent;

                if (expression != binaryExpression.Right)
                {
                    return;
                }

                if (binaryExpression.Left.ContainsDirectives)
                {
                    return;
                }

                if (binaryExpression.OperatorToken.ContainsDirectives)
                {
                    return;
                }

                NullCheckExpressionInfo nullCheckInfo = SyntaxInfo.NullCheckExpressionInfo(binaryExpression.Left, NullCheckStyles.CheckingNotNull & ~NullCheckStyles.HasValue);

                if (!nullCheckInfo.Success)
                {
                    return;
                }

                if (!CSharpFactory.AreEquivalent(invocationInfo.Expression, nullCheckInfo.Expression))
                {
                    return;
                }

                if (!CSharpSymbolUtility.IsIsKindExtensionMethod(invocationExpression, context.SemanticModel, context.CancellationToken))
                {
                    return;
                }

                TextSpan span = TextSpan.FromBounds(binaryExpression.Left.SpanStart, binaryExpression.OperatorToken.Span.End);

                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    DiagnosticDescriptors.UnnecessaryNullCheck,
                    Location.Create(invocationInfo.InvocationExpression.SyntaxTree, span));
            }

            void UseElementAccessInsteadOfCallingFirst()
            {
                if (!invocationInfo.Expression.GetTrailingTrivia().IsEmptyOrWhitespace())
                {
                    return;
                }

                symbol = context.SemanticModel.GetSymbol(invocationExpression, context.CancellationToken);

                if (symbol?.Kind != SymbolKind.Method ||
                    symbol.IsStatic ||
                    symbol.DeclaredAccessibility != Accessibility.Public ||
                    !RoslynSymbolUtility.IsList(symbol.ContainingType.OriginalDefinition))
                {
                    return;
                }

                TextSpan span = TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationExpression.Span.End);

                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    DiagnosticDescriptors.UseElementAccess,
                    Location.Create(invocationExpression.SyntaxTree, span));
            }

            void UseElementAccessInsteadOfCallingElementAt()
            {
                if (!invocationInfo.Expression.GetTrailingTrivia().IsEmptyOrWhitespace())
                {
                    return;
                }

                symbol = context.SemanticModel.GetSymbol(invocationExpression, context.CancellationToken);

                if (symbol?.Kind != SymbolKind.Method ||
                    symbol.IsStatic ||
                    symbol.DeclaredAccessibility != Accessibility.Public ||
                    !symbol.ContainingType.OriginalDefinition.HasMetadataName(RoslynMetadataNames.Microsoft_CodeAnalysis_SyntaxTriviaList))
                {
                    return;
                }

                TextSpan span = TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationExpression.Span.End);

                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    DiagnosticDescriptors.UseElementAccess,
                    Location.Create(invocationExpression.SyntaxTree, span));
            }

            void UseReturnValue()
            {
                if (symbol == null)
                {
                    symbol = context.SemanticModel.GetSymbol(invocationExpression, context.CancellationToken);
                }

                if (symbol?.Kind != SymbolKind.Method)
                {
                    return;
                }

                if (!RoslynSymbolUtility.IsRoslynType(symbol.ContainingType))
                {
                    return;
                }

                var methodSymbol = (IMethodSymbol)symbol;

                if (!RoslynSymbolUtility.IsRoslynType(methodSymbol.ReturnType))
                {
                    return;
                }

                DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseReturnValue, invocationExpression);
            }
        }