static DispatchTuple createFromWidget <TView, TEventArgs>(Expression <Func <TView, object> > property, Action <TView, EventHandler <TEventArgs> > addHandler, Action <TView, EventHandler <TEventArgs> > removeHandler)
            where TView : View
            where TEventArgs : EventArgs
        {
            // ExpressionToPropertyNames is used here as it handles boxing expressions that might
            // occur due to our use of object
            var propName = property.Body.GetMemberInfo().Name;

            return(new DispatchTuple {
                Type = typeof(TView),
                Property = propName,
                Func = (x, ex) => {
                    var v = (TView)x;

                    return Observable.FromEventPattern <TEventArgs>(h => addHandler(v, h), h => removeHandler(v, h))
                    .Select(_ => new ObservedChange <object, object>(v, ex));
                }
            });
        }
        private static DispatchTuple CreateFromAdapterView()
        {
            // AdapterView is more complicated because there are two events - one for select and one for deselect
            // respond to both
            const string propName = "SelectedItem";

            return(new DispatchTuple
            {
                Type = typeof(AdapterView),
                Property = propName,
                Func = (x, ex) =>
                {
                    var v = (AdapterView)x;

                    return Observable.Merge(
                        Observable.FromEventPattern <AdapterView.ItemSelectedEventArgs>(h => v.ItemSelected += h, h => v.ItemSelected -= h)
                        .Select(_ => new ObservedChange <object, object>(v, ex)),
                        Observable.FromEventPattern <AdapterView.NothingSelectedEventArgs>(h => v.NothingSelected += h, h => v.NothingSelected -= h)
                        .Select(_ => new ObservedChange <object, object>(v, ex)));
                }
            });
        }