private static IDisposable RegisterService <TEvent>(
            this IEventStream eventStream,
            Action onStart,
            Action onStop,
            Action onPrepare       = null,
            Action <TEvent> onNext = null,
            string name            = null)
        {
            var disposables = new CompositeDisposable(capacity: 4);

            if (onNext != null)
            {
                eventStream
                .OfType <TEvent>()
                .Subscribe(onNext)
                .DisposeWith(disposables);
            }

            if (onPrepare != null)
            {
                eventStream
                .OfType <IRequestFor <TEvent> >()
                .Subscribe(_ => onPrepare())
                .DisposeWith(disposables);
            }

            if (onStart != null)
            {
                eventStream
                .OfType <ISubscriptionOf <TEvent> >()
                .Subscribe(_ =>
                {
                    onStart();

                    eventStream.Push(new ServiceStartedEvent(name));
                })
                .DisposeWith(disposables);
            }

            if (onStop == null)
            {
                eventStream
                .OfType <IUnsubscriptionOf <TEvent> >()
                .Subscribe(_ =>
                {
                    onStop();

                    eventStream.Push(new ServiceStoppedEvent(name));
                })
                .DisposeWith(disposables);
            }

            eventStream.Push(new ServiceRegisteredEvent(name));

            return(disposables);
        }
        /// <summary>
        /// Observes the events of a given name.
        /// </summary>
        public static IObservable <Unit> OfName(
            this IEventStream eventStream,
            string name)
        {
            var none = Unit.Default;

            return(eventStream
                   .OfType <string>()
                   .Where(_ => _ == name)
                   .Select(_ => none)
                   .Merge(eventStream
                          .OfType <IStringEvent>()
                          .Where(_ => _.Name == name)
                          .Select(_ => none)));
        }
 /// <summary>
 /// Observes the events of a given name.
 /// </summary>
 private static IObservable <IStringEvent <T> > OfNamedString <T>(
     this IEventStream eventStream,
     string name)
 {
     return(eventStream
            .OfType <IStringEvent <T> >()
            .Where(_ => _.Name == name));
 }
 /// <summary>
 /// Observes the events of a given type.
 /// </summary>
 public static IDisposable OfType <TEvent>(
     this IEventStream eventStream,
     Action <TEvent> onNext)
 {
     return(eventStream.OfType <TEvent>().Subscribe(onNext));
 }