private static void ImplementINotifyPropertyChanged(CodeFixContext context, SemanticModel semanticModel, ClassDeclarationSyntax classDeclaration, DocumentEditor editor)
        {
            var type             = (ITypeSymbol)semanticModel.GetDeclaredSymbol(classDeclaration, context.CancellationToken);
            var underscoreFields = CodeStyle.UnderscoreFields(semanticModel);

            if (!type.Is(KnownSymbol.INotifyPropertyChanged))
            {
                if (classDeclaration.BaseList != null &&
                    classDeclaration.BaseList.Types.TryFirst(
                        x => (x.Type as IdentifierNameSyntax)?.Identifier.ValueText.Contains("INotifyPropertyChanged") == true,
                        out var baseType) &&
                    context.Diagnostics.Any(IsINotifyPropertyChangedMissing))
                {
                    editor.ReplaceNode(baseType, SyntaxFactory.SimpleBaseType(INotifyPropertyChangedType));
                }
                else
                {
                    editor.AddInterfaceType(classDeclaration, INotifyPropertyChangedType);
                }
            }

            if (!type.TryFindEventRecursive("PropertyChanged", out _))
            {
                editor.AddEvent(
                    classDeclaration,
                    (EventFieldDeclarationSyntax)editor.Generator.EventDeclaration(
                        "PropertyChanged",
                        PropertyChangedEventHandlerType,
                        Accessibility.Public));
            }

            if (!type.TryFindFirstMethodRecursive(
                    "OnPropertyChanged",
                    m => m.Parameters.Length == 1 &&
                    m.Parameters[0]
                    .Type == KnownSymbol.String,
                    out _))
            {
                if (type.IsSealed)
                {
                    editor.AddMethod(
                        classDeclaration,
                        ParseMethod(
                            @"private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
                              {
                                  this.PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                              }",
                            underscoreFields));
                }
                else
                {
                    editor.AddMethod(
                        classDeclaration,
                        ParseMethod(
                            @"protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
                              {
                                  this.PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
                              }",
                            underscoreFields));
                }
            }
        }