public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, bool beforeChanged = false)
        {
            Contract.Requires(sender != null && sender is DependencyObject);
            var type = sender.GetType();
            var propertyName = expression.GetMemberInfo().Name;
            var depSender = sender as DependencyObject;

            if (depSender == null)
            {
                this.Log().Warn("Tried to bind DP on a non-DependencyObject. Binding as POCO object",
                    type.FullName, propertyName);

                var ret = new POCOObservableForProperty();
                return ret.GetNotificationForProperty(sender, expression, beforeChanged);
            }

            if (beforeChanged == true) {
                this.Log().Warn("Tried to bind DO {0}.{1}, but DPs can't do beforeChanged. Binding as POCO object",
                    type.FullName, propertyName);

                var ret = new POCOObservableForProperty();
                return ret.GetNotificationForProperty(sender, expression, beforeChanged);
            }

            var dpFetcher = getDependencyPropertyFetcher(type, propertyName);
            if (dpFetcher == null) {
                this.Log().Warn("Tried to bind DO {0}.{1}, but DP doesn't exist. Binding as POCO object",
                    type.FullName, propertyName);

                var ret = new POCOObservableForProperty();
                return ret.GetNotificationForProperty(sender, expression, beforeChanged);
            }

#if WINDOWS_UWP
            return Observable.Create<IObservedChange<object, object>>(subj => {
                var handler = new DependencyPropertyChangedCallback((o, e) => {
                    subj.OnNext(new ObservedChange<object, object>(sender, expression));
                });
                var dependencyProperty = dpFetcher();
                var token = depSender.RegisterPropertyChangedCallback(dependencyProperty, handler);
                return Disposable.Create(() => depSender.UnregisterPropertyChangedCallback(dependencyProperty, token));
            });
#else
            var dpAndSubj = createAttachedProperty(type, propertyName);

            return Observable.Create<IObservedChange<object, object>>(obs => {
                BindingOperations.SetBinding(depSender, dpAndSubj.Item1,
                    new Binding() { Source = depSender, Path = new PropertyPath(propertyName) });

                var disp = dpAndSubj.Item2
                    .Where(x => x == sender)
                    .Select(x => new ObservedChange<object, object>(x, expression))
                    .Subscribe(obs);

                // ClearBinding calls ClearValue http://stackoverflow.com/questions/1639219/clear-binding-in-silverlight-remove-data-binding-from-setbinding
                return new CompositeDisposable(Disposable.Create(() => depSender.ClearValue(dpAndSubj.Item1)), disp);
            });
#endif
        }
        public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, bool beforeChanged = false)
        {
            var type = sender.GetType();
            var propertyName = expression.GetMemberInfo().Name;
            var dpd = DependencyPropertyDescriptor.FromProperty(getDependencyProperty(type, propertyName), type);

            return Observable.Create<IObservedChange<object, object>>(subj => {
                var handler = new EventHandler((o, e) => {
                    subj.OnNext(new ObservedChange<object, object>(sender, expression));
                });

                dpd.AddValueChanged(sender, handler);
                return Disposable.Create(() => dpd.RemoveValueChanged(sender, handler));
            });
        }
        public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, bool beforeChanged = false)
        {
            var type = sender.GetType();
            var propertyName = expression.GetMemberInfo().Name;
            var dpd = DependencyPropertyDescriptor.FromProperty(getDependencyProperty(type, propertyName), type);

            if (dpd == null) {
                this.Log().Error("Couldn't find dependency property " + propertyName + " on " + type.Name);
                throw new NullReferenceException("Couldn't find dependency property " + propertyName + " on " + type.Name);
            }

            return Observable.Create<IObservedChange<object, object>>(subj => {
                var handler = new EventHandler((o, e) => {
                    subj.OnNext(new ObservedChange<object, object>(sender, expression));
                });

                dpd.AddValueChanged(sender, handler);
                return Disposable.Create(() => dpd.RemoveValueChanged(sender, handler));
            });
        }