/// <summary>
        /// <para>Converts NotificationObject's property to ReactiveProperty. Value is two-way synchronized.</para>
        /// <para>PropertyChanged raise on selected scheduler.</para>
        /// </summary>
        /// <param name="propertySelector">Argument is self, Return is target property.</param>
        /// <param name="convert">Convert selector to ReactiveProperty.</param>
        /// <param name="convertBack">Convert selector to source.</param>
        /// <param name="mode">ReactiveProperty mode.</param>
        public static ReactiveProperty <TResult> ToReactivePropertyAsSynchronized <TSubject, TProperty, TResult>(
            this TSubject subject,
            Expression <Func <TSubject, TProperty> > propertySelector,
            Func <TProperty, TResult> convert,
            Func <TResult, TProperty> convertBack,
            IScheduler raiseEventScheduler,
            ReactivePropertyMode mode = ReactivePropertyMode.DistinctUntilChanged | ReactivePropertyMode.RaiseLatestValueOnSubscribe)
            where TSubject : INotifyPropertyChanged
        {
            string propertyName; // no use
            var    setter = AccessorCache <TSubject> .LookupSet(propertySelector, out propertyName);

            var result = subject.ObserveProperty(propertySelector, isPushCurrentValueAtFirst: true)
                         .Select(convert)
                         .ToReactiveProperty(raiseEventScheduler, mode: mode);

            result.Select(convertBack).Subscribe(x => setter(subject, x));
            return(result);
        }
        /// <summary>
        /// Converts NotificationObject's property changed to an observable sequence.
        /// </summary>
        /// <param name="propertySelector">Argument is self, Return is target property.</param>
        /// <param name="isPushCurrentValueOnSubscribe">Push current value on first subscribe.</param>
        public static IObservable <TProperty> ObserveProperty <TSubject, TProperty>(
            this TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector,
            bool isPushCurrentValueAtFirst = true)
            where TSubject : INotifyPropertyChanged
        {
            string propertyName;
            var    accessor = AccessorCache <TSubject> .LookupGet(propertySelector, out propertyName);

            var isFirst = true;

            var result = Observable.Defer(() =>
            {
                var flag = isFirst;
                isFirst  = false;

                var q = subject.PropertyChangedAsObservable()
                        .Where(e => e.PropertyName == propertyName)
                        .Select(_ => accessor.Invoke(subject));
                return((isPushCurrentValueAtFirst && flag) ? q.StartWith(accessor.Invoke(subject)) : q);
            });

            return(result);
        }