private static TSource SingleOrDefaultInternal <TSource>(IObservable <TSource> source, bool throwOnEmpty)
        {
            var value = default(TSource);

            var seenValue          = false;
            var moreThanOneElement = false;
            var ex = default(Exception);

            using (var evt = new WaitAndSetOnce())
            {
                //
                // [OK] Use of unsafe Subscribe: fine to throw to our caller, behavior indistinguishable from going through the sink.
                //
                using (source.Subscribe/*Unsafe*/ (new AnonymousObserver <TSource>(
                                                       v =>
                {
                    if (seenValue)
                    {
                        moreThanOneElement = true;
                        evt.Set();
                    }

                    value = v;
                    seenValue = true;
                },
                                                       e =>
                {
                    ex = e;
                    evt.Set();
                },
                                                       () =>
                {
                    evt.Set();
                })))
                {
                    evt.WaitOne();
                }
            }

            ex.ThrowIfNotNull();

            if (moreThanOneElement)
            {
                throw new InvalidOperationException(Strings_Linq.MORE_THAN_ONE_ELEMENT);
            }

            if (throwOnEmpty && !seenValue)
            {
                throw new InvalidOperationException(Strings_Linq.NO_ELEMENTS);
            }

            return(value);
        }
        public virtual void ForEach <TSource>(IObservable <TSource> source, Action <TSource, int> onNext)
        {
            using (var evt = new WaitAndSetOnce())
            {
                var sink = new ForEach <TSource> .ObserverIndexed(onNext, () => evt.Set());

                using (source.SubscribeSafe(sink))
                {
                    evt.WaitOne();
                }

                sink.Error.ThrowIfNotNull();
            }
        }
        public virtual void ForEach <TSource>(IObservable <TSource> source, Action <TSource> onNext)
        {
#if !NO_PERF
            using (var evt = new WaitAndSetOnce())
            {
                var sink = new ForEach <TSource> ._(onNext, () => evt.Set());

                using (source.SubscribeSafe(sink))
                {
                    evt.WaitOne();
                }

                sink.Error.ThrowIfNotNull();
            }
#else
            ForEach_(source, onNext);
#endif
        }