private static void AnalyzeSummaryElement(SyntaxNodeAnalysisContext context, XmlNodeSyntax syntax, Location diagnosticLocation, PropertyDeclarationSyntax propertyDeclaration, string startingTextGets, string startingTextSets, string startingTextGetsOrSets)
        {
            var diagnosticProperties = ImmutableDictionary.CreateBuilder<string, string>();
            ArrowExpressionClauseSyntax expressionBody = propertyDeclaration.ExpressionBody;
            AccessorDeclarationSyntax getter = null;
            AccessorDeclarationSyntax setter = null;

            if (propertyDeclaration.AccessorList != null)
            {
                foreach (var accessor in propertyDeclaration.AccessorList.Accessors)
                {
                    switch (accessor.Keyword.Kind())
                    {
                    case SyntaxKind.GetKeyword:
                        getter = accessor;
                        break;

                    case SyntaxKind.SetKeyword:
                        setter = accessor;
                        break;
                    }
                }
            }

            XmlElementSyntax summaryElement = (XmlElementSyntax)syntax;
            if (summaryElement == null)
            {
                // This is reported by SA1604.
                return;
            }

            // Add a no code fix tag when the summary element is empty.
            // This will only impact SA1623, because SA1624 cannot trigger with an empty summary.
            if (summaryElement.Content.Count == 0)
            {
                diagnosticProperties.Add(NoCodeFixKey, string.Empty);
            }

            var textElement = summaryElement.Content.FirstOrDefault() as XmlTextSyntax;
            var text = textElement == null ? string.Empty : XmlCommentHelper.GetText(textElement, true).TrimStart();

            if (getter != null || expressionBody != null)
            {
                bool startsWithGetOrSet = text.StartsWith(startingTextGetsOrSets, StringComparison.Ordinal);

                if (setter != null)
                {
                    // There is no way getter is null (can't have expression body and accessor list)
                    bool getterVisible;
                    bool setterVisible;

                    if (!getter.Modifiers.Any() && !setter.Modifiers.Any())
                    {
                        // Case 1: The getter and setter have the same declared accessibility
                        getterVisible = true;
                        setterVisible = true;
                    }
                    else if (getter.Modifiers.Any(SyntaxKind.PrivateKeyword))
                    {
                        // Case 3
                        getterVisible = false;
                        setterVisible = true;
                    }
                    else if (setter.Modifiers.Any(SyntaxKind.PrivateKeyword))
                    {
                        // Case 3
                        getterVisible = true;
                        setterVisible = false;
                    }
                    else
                    {
                        var propertyAccessibility = propertyDeclaration.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken);
                        bool propertyOnlyInternal = propertyAccessibility == Accessibility.Internal
                            || propertyAccessibility == Accessibility.ProtectedAndInternal
                            || propertyAccessibility == Accessibility.Private;
                        if (propertyOnlyInternal)
                        {
                            // Case 2: Property only internal and no accessor is explicitly private
                            getterVisible = true;
                            setterVisible = true;
                        }
                        else
                        {
                            var getterAccessibility = getter.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken);
                            var setterAccessibility = setter.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken);

                            switch (getterAccessibility)
                            {
                            case Accessibility.Public:
                            case Accessibility.ProtectedOrInternal:
                            case Accessibility.Protected:
                                // Case 4
                                getterVisible = true;
                                break;

                            case Accessibility.Internal:
                            case Accessibility.ProtectedAndInternal:
                            case Accessibility.Private:
                            default:
                                // The property is externally accessible, so the setter must be more accessible.
                                getterVisible = false;
                                break;
                            }

                            switch (setterAccessibility)
                            {
                            case Accessibility.Public:
                            case Accessibility.ProtectedOrInternal:
                            case Accessibility.Protected:
                                // Case 4
                                setterVisible = true;
                                break;

                            case Accessibility.Internal:
                            case Accessibility.ProtectedAndInternal:
                            case Accessibility.Private:
                            default:
                                // The property is externally accessible, so the getter must be more accessible.
                                setterVisible = false;
                                break;
                            }
                        }
                    }

                    if (getterVisible && !setterVisible)
                    {
                        if (startsWithGetOrSet)
                        {
                            diagnosticProperties.Add(ExpectedTextKey, startingTextGets);
                            diagnosticProperties.Add(TextToRemoveKey, startingTextGetsOrSets);
                            context.ReportDiagnostic(Diagnostic.Create(SA1624Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), "get", startingTextGets));
                        }
                        else if (!text.StartsWith(startingTextGets, StringComparison.Ordinal))
                        {
                            diagnosticProperties.Add(ExpectedTextKey, startingTextGets);
                            context.ReportDiagnostic(Diagnostic.Create(SA1623Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), startingTextGets));
                        }
                    }
                    else if (!getterVisible && setterVisible)
                    {
                        if (startsWithGetOrSet)
                        {
                            diagnosticProperties.Add(ExpectedTextKey, startingTextSets);
                            diagnosticProperties.Add(TextToRemoveKey, startingTextGetsOrSets);
                            context.ReportDiagnostic(Diagnostic.Create(SA1624Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), "set", startingTextSets));
                        }
                        else if (!text.StartsWith(startingTextSets, StringComparison.Ordinal))
                        {
                            diagnosticProperties.Add(ExpectedTextKey, startingTextSets);
                            context.ReportDiagnostic(Diagnostic.Create(SA1623Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), startingTextSets));
                        }
                    }
                    else
                    {
                        if (!startsWithGetOrSet)
                        {
                            diagnosticProperties.Add(ExpectedTextKey, startingTextGetsOrSets);
                            context.ReportDiagnostic(Diagnostic.Create(SA1623Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), startingTextGetsOrSets));
                        }
                    }
                }
                else
                {
                    if (startsWithGetOrSet || !text.StartsWith(startingTextGets, StringComparison.Ordinal))
                    {
                        diagnosticProperties.Add(ExpectedTextKey, startingTextGets);
                        context.ReportDiagnostic(Diagnostic.Create(SA1623Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), startingTextGets));
                    }
                }
            }
            else if (setter != null)
            {
                if (!text.StartsWith(startingTextSets, StringComparison.Ordinal))
                {
                    diagnosticProperties.Add(ExpectedTextKey, startingTextSets);
                    context.ReportDiagnostic(Diagnostic.Create(SA1623Descriptor, diagnosticLocation, diagnosticProperties.ToImmutable(), startingTextSets));
                }
            }
        }