// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System.Reactive.Concurrency;
using System.Threading;
namespace System.Reactive.Linq
{
	public static partial class Observable
    {
        #region + ObserveOn +
        /// 
        /// Wraps the source sequence in order to run its observer callbacks on the specified scheduler.
        /// 
        /// The type of the elements in the source sequence.
        /// Source sequence.
        /// Scheduler to notify observers on.
        /// The source sequence whose observations happen on the specified scheduler.
        ///  or  is null.
        /// 
        /// This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects
        /// that require to be run on a scheduler, use .
        /// 
        public static IObservable ObserveOn(this IObservable source, IScheduler scheduler)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (scheduler == null)
                throw new ArgumentNullException("scheduler");
            return s_impl.ObserveOn(source, scheduler);
        }
#if !NO_SYNCCTX
        /// 
        /// Wraps the source sequence in order to run its observer callbacks on the specified synchronization context.
        /// 
        /// The type of the elements in the source sequence.
        /// Source sequence.
        /// Synchronization context to notify observers on.
        /// The source sequence whose observations happen on the specified synchronization context.
        ///  or  is null.
        /// 
        /// This only invokes observer callbacks on a synchronization context. In case the subscription and/or unsubscription actions have side-effects
        /// that require to be run on a synchronization context, use .
        /// 
        public static IObservable ObserveOn(this IObservable source, SynchronizationContext context)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (context == null)
                throw new ArgumentNullException("context");
            return s_impl.ObserveOn(source, context);
        }
#endif
        #endregion
        #region + SubscribeOn +
        /// 
        /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used;
        /// see the remarks section for more information on the distinction between SubscribeOn and ObserveOn.
        /// 
        /// The type of the elements in the source sequence.
        /// Source sequence.
        /// Scheduler to perform subscription and unsubscription actions on.
        /// The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler.
        ///  or  is null.
        /// 
        /// This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer
        /// callbacks on a scheduler, use .
        /// 
        public static IObservable SubscribeOn(this IObservable source, IScheduler scheduler)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (scheduler == null)
                throw new ArgumentNullException("scheduler");
            return s_impl.SubscribeOn(source, scheduler);
        }
#if !NO_SYNCCTX
        /// 
        /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified synchronization context. This operation is not commonly used;
        /// see the remarks section for more information on the distinction between SubscribeOn and ObserveOn.
        /// 
        /// The type of the elements in the source sequence.
        /// Source sequence.
        /// Synchronization context to perform subscription and unsubscription actions on.
        /// The source sequence whose subscriptions and unsubscriptions happen on the specified synchronization context.
        ///  or  is null.
        /// 
        /// This only performs the side-effects of subscription and unsubscription on the specified synchronization context. In order to invoke observer
        /// callbacks on a synchronization context, use .
        /// 
        public static IObservable SubscribeOn(this IObservable source, SynchronizationContext context)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (context == null)
                throw new ArgumentNullException("context");
            return s_impl.SubscribeOn(source, context);
        }
#endif
        #endregion
        #region + Synchronize +
        /// 
        /// Synchronizes the observable sequence such that observer notifications cannot be delivered concurrently.
        /// This overload is useful to "fix" an observable sequence that exhibits concurrent callbacks on individual observers, which is invalid behavior for the query processor.
        /// 
        /// The type of the elements in the source sequence.
        /// Source sequence.
        /// The source sequence whose outgoing calls to observers are synchronized.
        ///  is null.
        /// 
        /// It's invalid behavior - according to the observer grammar - for a sequence to exhibit concurrent callbacks on a given observer.
        /// This operator can be used to "fix" a source that doesn't conform to this rule.
        /// 
        public static IObservable Synchronize(this IObservable source)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            return s_impl.Synchronize(source);
        }
        /// 
        /// Synchronizes the observable sequence such that observer notifications cannot be delivered concurrently, using the specified gate object.
        /// This overload is useful when writing n-ary query operators, in order to prevent concurrent callbacks from different sources by synchronizing on a common gate object.
        /// 
        /// The type of the elements in the source sequence.
        /// Source sequence.
        /// Gate object to synchronize each observer call on.
        /// The source sequence whose outgoing calls to observers are synchronized on the given gate object.
        ///  or  is null.
        public static IObservable Synchronize(this IObservable source, object gate)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            if (gate == null)
                throw new ArgumentNullException("gate");
            return s_impl.Synchronize(source, gate);
        }
        #endregion
    }
}