public void PropertyChangedEventArgsBeforeCallerMemberName()
            {
                var syntaxTree = CSharpSyntaxTree.ParseText(
                    @"
namespace RoslynSandbox
{
    using System.ComponentModel;
    using System.Runtime.CompilerServices;

    public class Foo : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public int Bar { get; set; }

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            this.PropertyChanged?.Invoke(this, e);
        }

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}");
                var compilation      = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
                var semanticModel    = compilation.GetSemanticModel(syntaxTree);
                var classDeclaration = syntaxTree.FindClassDeclaration("Foo");
                var type             = semanticModel.GetDeclaredSymbol(classDeclaration);

                Assert.AreEqual(true, PropertyChanged.TryGetOnPropertyChanged(type, semanticModel, CancellationToken.None, out var invoker));
                Assert.AreEqual("RoslynSandbox.Foo.OnPropertyChanged(string)", invoker.ToString());
            }
            public void WhenCreatingPropertyChangedEventArgsSeparately()
            {
                var syntaxTree = CSharpSyntaxTree.ParseText(@"
namespace RoslynSandbox
{
    using System.ComponentModel;
    using System.Runtime.CompilerServices;

    public class Foo : INotifyPropertyChanged
    {
        private int bar;

        public event PropertyChangedEventHandler PropertyChanged;

        public int Bar
        {
            get => this.bar;

            set
            {
                if (value == this.bar)
                {
                    return;
                }

                this.bar = value;
                this.OnPropertyChanged();
            }
        }

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                var args = new PropertyChangedEventArgs(propertyName);
                handler.Invoke(this, args);
            }
        }
    }
}");

                var compilation      = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
                var semanticModel    = compilation.GetSemanticModel(syntaxTree);
                var classDeclaration = syntaxTree.FindClassDeclaration("Foo");
                var type             = semanticModel.GetDeclaredSymbol(classDeclaration);

                Assert.AreEqual(true, PropertyChanged.TryGetOnPropertyChanged(type, semanticModel, CancellationToken.None, out var invoker));
                Assert.AreEqual("RoslynSandbox.Foo.OnPropertyChanged(string)", invoker.ToString());
            }
            public void OverridingEvent()
            {
                var viewModelBaseCode = CSharpSyntaxTree.ParseText(@"
namespace RoslynSandbox
{
    using System.ComponentModel;
    using System.Runtime.CompilerServices;

    public class ViewModelBase : INotifyPropertyChanged
    {
        public virtual event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}");

                var testCode = CSharpSyntaxTree.ParseText(@"
namespace RoslynSandbox
{
    using System.ComponentModel;

    public class ViewModel : RoslynSandbox.ViewModelBase
    {
        public override event PropertyChangedEventHandler PropertyChanged;
    }
}");

                var compilation      = CSharpCompilation.Create("test", new[] { viewModelBaseCode, testCode }, MetadataReferences.FromAttributes());
                var semanticModel    = compilation.GetSemanticModel(testCode);
                var classDeclaration = testCode.FindClassDeclaration("ViewModel");
                var type             = semanticModel.GetDeclaredSymbol(classDeclaration);

                Assert.AreEqual(true, PropertyChanged.TryGetOnPropertyChanged(type, semanticModel, CancellationToken.None, out var invoker));
                Assert.AreEqual("RoslynSandbox.ViewModelBase.OnPropertyChanged(string)", invoker.ToString());
            }