protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSymbolAction(
                c =>
                {
                    var namedType = (INamedTypeSymbol)c.Symbol;
                    if (!namedType.IsClassOrStruct() ||
                        namedType.ContainingType != null)
                    {
                        return;
                    }

                    var removableDeclarationCollector = new RemovableDeclarationCollector(namedType, c.Compilation);

                    var candidateFields = removableDeclarationCollector.GetRemovableFieldLikeDeclarations(
                        ImmutableHashSet.Create(SyntaxKind.FieldDeclaration), maxAccessibility)
                        .Where(tuple => ((VariableDeclaratorSyntax)tuple.SyntaxNode).Initializer == null);

                    var candidateProperties = removableDeclarationCollector.GetRemovableDeclarations(
                        ImmutableHashSet.Create(SyntaxKind.PropertyDeclaration), maxAccessibility)
                        .Where(tuple => IsAutoPropertyWithNoInitializer((PropertyDeclarationSyntax)tuple.SyntaxNode));

                    var allCandidateMembers = candidateFields.Concat(candidateProperties).ToList();
                    if (!allCandidateMembers.Any())
                    {
                        return;
                    }

                    var usedMembers = GetMemberUsages(removableDeclarationCollector, new HashSet<ISymbol>(allCandidateMembers.Select(t => t.Symbol)));
                    var usedMemberSymbols = new HashSet<ISymbol>(usedMembers.Select(tuple => tuple.Symbol));

                    var assignedMemberSymbols = GetAssignedMemberSymbols(usedMembers);

                    foreach (var candidateMember in allCandidateMembers)
                    {
                        if (!usedMemberSymbols.Contains(candidateMember.Symbol))
                        {
                            /// reported by <see cref="UnusedPrivateMember"/>
                            continue;
                        }

                        if (!assignedMemberSymbols.Contains(candidateMember.Symbol))
                        {
                            var field = candidateMember.SyntaxNode as VariableDeclaratorSyntax;
                            var property = candidateMember.SyntaxNode as PropertyDeclarationSyntax;

                            var memberType = field != null ? "field" : "auto-property";

                            var location = field != null
                                ? field.Identifier.GetLocation()
                                : property.Identifier.GetLocation();

                            c.ReportDiagnosticIfNonGenerated(Diagnostic.Create(Rule, location, memberType, candidateMember.Symbol.Name));
                        }
                    }
                },
                SymbolKind.NamedType);
        }
        protected override void Initialize(SonarAnalysisContext context)
        {
            context.RegisterSymbolAction(
                c =>
                {
                    var namedType = (INamedTypeSymbol)c.Symbol;
                    if (!namedType.IsClassOrStruct() ||
                        namedType.ContainingType != null)
                    {
                        return;
                    }

                    var removableDeclarationCollector = new RemovableDeclarationCollector(namedType, c.Compilation);

                    var removableEvents = removableDeclarationCollector.GetRemovableDeclarations(
                        ImmutableHashSet.Create(SyntaxKind.EventDeclaration), maxAccessibility);
                    var removableEventFields = removableDeclarationCollector.GetRemovableFieldLikeDeclarations(
                        ImmutableHashSet.Create(SyntaxKind.EventFieldDeclaration), maxAccessibility);

                    var allRemovableEvents = removableEvents.Concat(removableEventFields).ToList();
                    if (!allRemovableEvents.Any())
                    {
                        return;
                    }

                    var symbolNames = allRemovableEvents.Select(t => t.Symbol.Name).ToImmutableHashSet();
                    var usedSymbols = GetReferencedSymbolsWithMatchingNames(removableDeclarationCollector, symbolNames);
                    var invokedSymbols = GetInvokedEventSymbols(removableDeclarationCollector);
                    var possiblyCopiedSymbols = GetPossiblyCopiedSymbols(removableDeclarationCollector);

                    foreach (var removableEvent in allRemovableEvents)
                    {
                        if (!usedSymbols.Contains(removableEvent.Symbol))
                        {
                            /// reported by <see cref="UnusedPrivateMember"/>
                            continue;
                        }

                        if (!invokedSymbols.Contains(removableEvent.Symbol) &&
                            !possiblyCopiedSymbols.Contains(removableEvent.Symbol))
                        {
                            var eventField = removableEvent.SyntaxNode as VariableDeclaratorSyntax;
                            var location = eventField != null
                                ? eventField.Identifier.GetLocation()
                                : ((EventDeclarationSyntax)removableEvent.SyntaxNode).Identifier.GetLocation();

                            c.ReportDiagnosticIfNonGenerated(Diagnostic.Create(Rule, location));
                        }
                    }
                },
                SymbolKind.NamedType);
        }
 private static void CollectRemovableEventsAndProperties(RemovableDeclarationCollector helper,
     HashSet<ISymbol> declaredPrivateSymbols)
 {
     var declarationKinds = ImmutableHashSet.Create(SyntaxKind.EventDeclaration, SyntaxKind.PropertyDeclaration, SyntaxKind.IndexerDeclaration);
     var declarations = helper.GetRemovableDeclarations(declarationKinds, maxAccessibility);
     declaredPrivateSymbols.UnionWith(declarations.Select(d => d.Symbol));
 }