public static void Analyze(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            ExtensionMethodSymbolInfo extensionInfo = semanticModel.GetReducedExtensionMethodInfo(invocationExpression, cancellationToken);

            if (extensionInfo.Symbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqCast(extensionInfo.Symbol, semanticModel))
            {
                return;
            }

            ITypeSymbol typeArgument = extensionInfo.ReducedSymbol.TypeArguments.SingleOrDefault(shouldThrow: false);

            if (typeArgument == null)
            {
                return;
            }

            var memberAccessExpressionType = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken) as INamedTypeSymbol;

            if (memberAccessExpressionType?.OriginalDefinition.IsIEnumerableOfT() != true)
            {
                return;
            }

            if (!typeArgument.Equals(memberAccessExpressionType.TypeArguments[0]))
            {
                return;
            }

            if (invocationExpression.ContainsDirectives(TextSpan.FromBounds(invocationInfo.Expression.Span.End, invocationExpression.Span.End)))
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.RemoveRedundantCast,
                Location.Create(invocationExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationInfo.ArgumentList.Span.End)));
        }
        public static void AnalyzeFirstOrDefault(SyntaxNodeAnalysisContext context, SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocation = invocationInfo.InvocationExpression;

            SyntaxNode parent = invocation.WalkUpParentheses().Parent;

            NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(parent, NullCheckStyles.ComparisonToNull | NullCheckStyles.IsNull);

            if (!nullCheck.Success)
            {
                return;
            }

            SyntaxNode node = nullCheck.NullCheckExpression;

            if (node.ContainsDirectives)
            {
                return;
            }

            ExtensionMethodSymbolInfo extensionMethodSymbolInfo = context.SemanticModel.GetReducedExtensionMethodInfo(invocation, context.CancellationToken);

            IMethodSymbol methodSymbol = extensionMethodSymbolInfo.Symbol;

            if (methodSymbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqExtensionOfIEnumerableOfTWithPredicate(methodSymbol, context.SemanticModel, name: invocationInfo.NameText, allowImmutableArrayExtension: true))
            {
                return;
            }

            if (!extensionMethodSymbolInfo
                .ReducedSymbol
                .ReturnType
                .IsReferenceTypeOrNullableType())
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.SimplifyLinqMethodChain, node);
        }
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            SimpleMemberInvocationExpressionInfo invocationInfo)
        {
            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            if (invocationInfo.Name.SpanOrTrailingTriviaContainsDirectives())
            {
                return;
            }

            if (invocationInfo.ArgumentList.SpanOrLeadingTriviaContainsDirectives())
            {
                return;
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            ExtensionMethodSymbolInfo extensionInfo = semanticModel.GetExtensionMethodInfo(invocationExpression, cancellationToken);

            if (extensionInfo.Symbol == null)
            {
                return;
            }

            if (!SymbolUtility.IsLinqSelect(extensionInfo.Symbol, semanticModel, allowImmutableArrayExtension: true))
            {
                return;
            }

            ITypeSymbol typeArgument = extensionInfo.ReducedSymbolOrSymbol.TypeArguments[0];

            if (!typeArgument.IsReferenceType)
            {
                return;
            }

            if (typeArgument.SpecialType == SpecialType.System_Object)
            {
                return;
            }

            ExpressionSyntax expression = invocationExpression.ArgumentList?.Arguments.Last().Expression;

            SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(expression);

            if (!lambdaInfo.Success)
            {
                return;
            }

            CastExpressionSyntax castExpression = GetCastExpression(lambdaInfo.Body);

            if (castExpression == null)
            {
                return;
            }

            if (!(castExpression.Expression is IdentifierNameSyntax identifierName))
            {
                return;
            }

            if (!string.Equals(lambdaInfo.Parameter.Identifier.ValueText, identifierName.Identifier.ValueText, StringComparison.Ordinal))
            {
                return;
            }

            var castSymbol = semanticModel.GetSymbol(castExpression, cancellationToken) as IMethodSymbol;

            if (castSymbol?.MethodKind == MethodKind.Conversion)
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.CallCastInsteadOfSelect,
                Location.Create(invocationExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationExpression.Span.End)));
        }