Inheritance: IDisposable
        public static IDisposable MakeDraggable(this Graphic graphic, Map map)
        {
            graphic.RequireArgument<Graphic>("graphic").NotNull<Graphic>();
            map.RequireArgument<Map>("map").NotNull<Map>();

            //IObservable<IEvent<MouseEventArgs>> graphicMouseMove = Observable.FromEvent
            //    (
            //        ( EventHandler<MouseEventArgs> ev ) => new MouseEventHandler( ev ),
            //        ev => graphic.MouseMove += ev,
            //        ev => graphic.MouseMove += ev
            //    );

            IObservable<IEvent<MouseEventArgs>> mapMouseMove = Observable.FromEvent
                (
                    (EventHandler<MouseEventArgs> ev) => new MouseEventHandler(ev),
                    ev => map.MouseMove += ev,
                    ev => map.MouseMove += ev
                );

            IObservable<IEvent<MouseButtonEventArgs>> graphicLeftMouseButtonDown = Observable.FromEvent
                (
                    (EventHandler<MouseButtonEventArgs> ev) => new MouseButtonEventHandler(ev),
                    ev => graphic.MouseLeftButtonDown += ev,
                    ev => graphic.MouseLeftButtonDown -= ev
                );

            //IObservable<IEvent<MouseButtonEventArgs>> graphicLeftMouseButtonUp = Observable.FromEvent
            //    (
            //        (EventHandler<MouseButtonEventArgs> ev) => new MouseButtonEventHandler(ev),
            //        ev => graphic.MouseLeftButtonUp += ev,
            //        ev => graphic.MouseLeftButtonUp -= ev
            //    );

            IObservable<IEvent<MouseButtonEventArgs>> mapLeftMouseButtonUp = Observable.FromEvent
                (
                    (EventHandler<MouseButtonEventArgs> ev) => new MouseButtonEventHandler(ev),
                    ev => map.MouseLeftButtonUp += ev,
                    ev => map.MouseLeftButtonUp -= ev
                );

            //var stopper = graphicLeftMouseButtonUp.Merge(mapLeftMouseButtonUp);
            //var dragger = graphicMouseMove.Merge(mapMouseMove);
            var stopper = mapLeftMouseButtonUp;
            var dragger = mapMouseMove;

            IObservable<IEvent<MouseEventArgs>> drag = dragger.SkipUntil(graphicLeftMouseButtonDown)
                .TakeUntil(stopper)
                .Repeat();

            Func<IEvent<MouseEventArgs>, IEvent<MouseEventArgs>, Unit> handler = (prev, cur) =>
            {
                var prevMapPoint = map.ScreenToMap(prev.EventArgs.GetPosition(map));
                var curMapPoint = map.ScreenToMap(cur.EventArgs.GetPosition(map));
                var deltaX = curMapPoint.X - prevMapPoint.X;
                var deltaY = curMapPoint.Y - prevMapPoint.Y;
                graphic.Geometry.Offset(deltaX, deltaY);
                return new Unit();
            };

            Disposables removeHandlers = new Disposables();
            removeHandlers.Subscriptions.Add(graphicLeftMouseButtonDown.Subscribe(e => e.EventArgs.Handled = true));
            removeHandlers.Subscriptions.Add
                (
                    drag
                    .Zip(drag.Skip(1), handler)
                    .Subscribe()
                );

            return removeHandlers;
        }
        public static IDisposable MakeDraggable(this GraphicsLayer gLayer, Map map)
        {
            gLayer.RequireArgument<GraphicsLayer>("gLayer").NotNull<GraphicsLayer>();
            map.RequireArgument<Map>("map").NotNull<Map>();

            IObservable<IEvent<MouseEventArgs>> dragger = Observable.FromEvent
                (
                    (EventHandler<MouseEventArgs> ev) => new MouseEventHandler(ev),
                    ev => map.MouseMove += ev,
                    ev => map.MouseMove += ev
                );

            IObservable<IEvent<GraphicMouseButtonEventArgs>> starter = Observable.FromEvent
                (
                    (EventHandler<GraphicMouseButtonEventArgs> ev) => new GraphicsLayer.MouseButtonEventHandler(ev),
                    ev => gLayer.MouseLeftButtonDown += ev,
                    ev => gLayer.MouseLeftButtonDown -= ev
                );

            IObservable<IEvent<MouseButtonEventArgs>> stopper = Observable.FromEvent
                (
                    (EventHandler<MouseButtonEventArgs> ev) => new MouseButtonEventHandler(ev),
                    ev => map.MouseLeftButtonUp += ev,
                    ev => map.MouseLeftButtonUp -= ev
                );

            IObservable<IEvent<MouseEventArgs>> drag = dragger.SkipUntil(starter)
                .TakeUntil(stopper)
                .Repeat();

            Guid state = Guid.NewGuid();
            Guid lastState = state;
            Graphic g = null;
            Func<IEvent<MouseEventArgs>, IEvent<MouseEventArgs>, Unit> handler = (prev, cur) =>
            {
                if (g == null)
                    return new Unit();
                if (state != lastState)
                {
                    lastState = state;
                    return new Unit();
                }
                var prevMapPoint = map.ScreenToMap(prev.EventArgs.GetPosition(map));
                var curMapPoint = map.ScreenToMap(cur.EventArgs.GetPosition(map));
                g.Geometry.Offset((curMapPoint.X - prevMapPoint.X), (curMapPoint.Y - prevMapPoint.Y));
                lastState = state;
                return new Unit();
            };

            Disposables removeHandlers = new Disposables();
            removeHandlers.Subscriptions.Add(starter.Subscribe(e =>
            {
                g = e.EventArgs.Graphic;
                state = Guid.NewGuid();
                e.EventArgs.Handled = true;
            }
            ));
            removeHandlers.Subscriptions.Add(stopper.Subscribe(e =>
            {
                state = Guid.NewGuid();
                g = null;
            }));
            removeHandlers.Subscriptions.Add
                (
                    drag
                    .Zip(drag.Skip(1), handler)
                    .Subscribe()
                );

            return removeHandlers;
        }