public async Task ExecuteServerAsync(IQbservableProvider provider)
        {
            Contract.Requires(!IsClient);

            Task receivingAsync = null;
            ExceptionDispatchInfo fatalException = null;

            try
            {
                await InitializeSinksAsync().ConfigureAwait(false);

                var input = await ServerReceiveQueryAsync().ConfigureAwait(false);

                receivingAsync = ServerReceiveAsync();

                try
                {
                    await ExecuteServerQueryAsync(input, provider).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    if (ShutdownReason == QbservableProtocolShutdownReason.None)
                    {
                        ShutdownReason = QbservableProtocolShutdownReason.BadClientRequest;
                    }

                    CancelAllCommunication(ex);

                    fatalException = ExceptionDispatchInfo.Capture(ex);
                }
            }
            catch (OperationCanceledException ex)
            {
                if (errors.Count == 1)
                {
                    if (ShutdownReason == QbservableProtocolShutdownReason.None)
                    {
                        ShutdownReason = QbservableProtocolShutdownReason.ServerError;
                    }

                    fatalException = errors[0];
                }
                else if (errors.Count > 1)
                {
                    if (ShutdownReason == QbservableProtocolShutdownReason.None)
                    {
                        ShutdownReason = QbservableProtocolShutdownReason.ServerError;
                    }

                    fatalException = ExceptionDispatchInfo.Capture(new AggregateException(errors.Select(e => e.SourceException)));
                }

                if (ShutdownReason == QbservableProtocolShutdownReason.None)
                {
                    ShutdownReason = QbservableProtocolShutdownReason.ClientTerminated;
                }

                fatalException = ExceptionDispatchInfo.Capture(ex);
            }
            catch (Exception ex)
            {
                CancelAllCommunication(ex);

                fatalException = ExceptionDispatchInfo.Capture(ex);
            }

            if (receivingAsync != null)
            {
                try
                {
                    await receivingAsync.ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    errors.Add(ExceptionDispatchInfo.Capture(ex));
                }
            }

            if (fatalException != null)
            {
                fatalException.Throw();
            }
        }
        private async Task SendObservableAsync(object untypedObservable, Type dataType, bool sendServerErrorsToClients, CancellationToken cancel)
        {
            var networkErrors = new ConcurrentBag <ExceptionDispatchInfo>();

            ExceptionDispatchInfo expressionSecurityError     = null;
            ExceptionDispatchInfo qbservableSubscriptionError = null;
            ExceptionDispatchInfo qbservableError             = null;

            var terminationKind = NotificationKind.OnCompleted;

            try
            {
                var cancelSubscription = new CancellationTokenSource();

                cancel.Register(cancelSubscription.Cancel);

                IObservable <object> observable;

                new PermissionSet(PermissionState.Unrestricted).Assert();

                try
                {
                    observable = dataType.UpCast(untypedObservable);
                }
                finally
                {
                    PermissionSet.RevertAssert();
                }

                await observable.ForEachAsync(
                    async data =>
                {
                    try
                    {
                        await ServerSendAsync(NotificationKind.OnNext, data).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException)
                    {
                    }
                    catch (Exception ex)
                    {
                        /* Collecting exceptions handles a possible race condition.  Since this code is using a fire-and-forget model to
                         * subscribe to the observable, due to the async OnNext handler, it's possible that more than one SendAsync task
                         * can be executing concurrently.  As a result, cancelling the cancelSubscription below does not guarantee that
                         * this catch block won't run again.
                         */
                        networkErrors.Add(ExceptionDispatchInfo.Capture(ex));

                        cancelSubscription.Cancel();
                    }
                },
                    cancelSubscription.Token)
                .ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                if (cancel.IsCancellationRequested && networkErrors.Count == 0)
                {
                    throw;
                }
            }
            catch (ExpressionSecurityException ex)
            {
                ShutdownReason = QbservableProtocolShutdownReason.ExpressionSecurityViolation;

                expressionSecurityError = ExceptionDispatchInfo.Capture(ex);
            }
            catch (QbservableSubscriptionException ex)
            {
                ShutdownReason = QbservableProtocolShutdownReason.ExpressionSubscriptionException;

                qbservableSubscriptionError = ExceptionDispatchInfo.Capture(ex.InnerException ?? ex);
            }
            catch (TargetInvocationException ex)
            {
                if (ex.InnerException is QbservableSubscriptionException)
                {
                    ShutdownReason = QbservableProtocolShutdownReason.ExpressionSubscriptionException;

                    qbservableSubscriptionError = ExceptionDispatchInfo.Capture(ex.InnerException.InnerException ?? ex.InnerException);
                }
                else
                {
                    qbservableSubscriptionError = ExceptionDispatchInfo.Capture(ex);
                }
            }
            catch (Exception ex)
            {
                terminationKind = NotificationKind.OnError;
                qbservableError = ExceptionDispatchInfo.Capture(ex);
            }

            var error = expressionSecurityError ?? qbservableSubscriptionError;

            if (error != null)
            {
                if (networkErrors.Count > 0)
                {
                    // It's not technically a network error, but since the client can't receive it anyway add it so that it's thrown later
                    networkErrors.Add(error);
                }
                else
                {
                    if (sendServerErrorsToClients || expressionSecurityError != null)
                    {
                        var exception = expressionSecurityError == null
              ? error.SourceException
              : new SecurityException(error.SourceException.Message);   // Remove stack trace

                        await ServerSendAsync(NotificationKind.OnError, exception).ConfigureAwait(false);
                    }

                    error.Throw();
                }
            }

            /* There's an acceptable race condition here whereby ForEachAsync is canceled by the external cancellation token though
             * it's still executing a fire-and-forget task.  It's possible for the fire-and-forget task to throw before seeing the
             * cancellation, yet after the following code has already executed.  In that case, since the cancellation was requested
             * externally, it's acceptable for the cancellation to simply beat the send error, thus the error can safely be ignored.
             */
            if (networkErrors.Count > 0)
            {
                throw new AggregateException(networkErrors.Select(e => e.SourceException));
            }
            else
            {
                await ServerSendAsync(terminationKind, (qbservableError == null ? null : qbservableError.SourceException)).ConfigureAwait(false);

                if (qbservableError != null)
                {
                    qbservableError.Throw();
                }
            }
        }
        private static IObservable <TcpClientTermination> CreateService <TSource, TResult>(
            IPEndPoint endPoint,
            Func <IRemotingFormatter> formatterFactory,
            QbservableServiceOptions options,
            Func <IObservable <TSource>, IQbservable <TResult> > service)
        {
            var listener = new TcpListener(endPoint);

            listener.Start();

            return(Observable
                   .FromAsync(listener.AcceptTcpClientAsync)
                   .Repeat()
                   .Finally(listener.Stop)
                   .SelectMany(client => Observable
                               .StartAsync(async cancel =>
            {
                var watch = Stopwatch.StartNew();

                var localEndPoint = client.Client.LocalEndPoint;
                var remoteEndPoint = client.Client.RemoteEndPoint;

                var exceptions = new List <ExceptionDispatchInfo>();
                var shutdownReason = QbservableProtocolShutdownReason.None;

                try
                {
                    using (var stream = client.GetStream())
                        using (var protocol = await QbservableProtocol.NegotiateServerAsync(stream, formatterFactory(), options, cancel).ConfigureAwait(false))
                        {
                            var provider = new TcpServerQbservableProvider <TResult>(
                                protocol,
                                options,
                                argument =>
                            {
                                if (argument == null && typeof(TSource).IsValueType)
                                {
                                    return service(Observable.Return(default(TSource)));
                                }
                                else
                                {
                                    return service(Observable.Return((TSource)argument));
                                }
                            });

                            try
                            {
                                await protocol.ExecuteServerAsync(provider).ConfigureAwait(false);
                            }
                            catch (OperationCanceledException)
                            {
                            }
                            catch (Exception ex)
                            {
                                exceptions.Add(ExceptionDispatchInfo.Capture(ex));
                            }

                            var protocolExceptions = protocol.Exceptions;

                            if (protocolExceptions != null)
                            {
                                foreach (var exception in protocolExceptions)
                                {
                                    exceptions.Add(exception);
                                }
                            }

                            shutdownReason = protocol.ShutdownReason;
                        }
                }
                catch (OperationCanceledException)
                {
                    shutdownReason = QbservableProtocolShutdownReason.ProtocolNegotiationCanceled;
                }
                catch (Exception ex)
                {
                    shutdownReason = QbservableProtocolShutdownReason.ProtocolNegotiationError;

                    exceptions.Add(ExceptionDispatchInfo.Capture(ex));
                }

                return new TcpClientTermination(localEndPoint, remoteEndPoint, watch.Elapsed, shutdownReason, exceptions);
            })
                               .Finally(client.Close)));
        }