async Task SendUsingNewModel(IPipe <ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            IPipe <ConnectionContext> connectionPipe = Pipe.ExecuteAsync <ConnectionContext>(async connectionContext =>
            {
                try
                {
                    if (_log.IsDebugEnabled)
                    {
                        _log.DebugFormat("Creating model: {0}", connectionContext.HostSettings.ToDebugString());
                    }

                    var model = await connectionContext.CreateModel().ConfigureAwait(false);

                    EventHandler <ShutdownEventArgs> modelShutdown = null;
                    modelShutdown = (obj, reason) =>
                    {
                        model.ModelShutdown -= modelShutdown;

                        Interlocked.CompareExchange(ref _scope, null, scope);

                        scope.Shutdown(reason.ReplyText);
                    };

                    model.ModelShutdown += modelShutdown;

                    var modelContext = new RabbitMqModelContext(connectionContext, model, _cacheTaskScope, _host);

                    scope.Created(modelContext);
                }
                catch (Exception ex)
                {
                    Interlocked.CompareExchange(ref _scope, null, scope);

                    scope.CreateFaulted(ex);

                    throw;
                }

                await SendUsingExistingModel(modelPipe, scope, cancellationToken).ConfigureAwait(false);
            });

            try
            {
                await _host.ConnectionCache.Send(connectionPipe, _cacheTaskScope.StoppedToken).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("The connection threw an exception", exception);
                }

                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.CreateFaulted(exception);

                throw;
            }
        }
        async Task SendUsingExistingModel(IPipe <ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            try
            {
                using (var context = await scope.Attach(cancellationToken).ConfigureAwait(false))
                {
//                    if (_log.IsDebugEnabled)
//                        _log.DebugFormat("Using model: {0}", ((ModelContext)context).ConnectionContext.HostSettings.ToDebugString());

                    await modelPipe.Send(context).ConfigureAwait(false);
                }
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                {
                    _log.Debug("The model usage threw an exception", exception);
                }

                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.CreateFaulted(exception);

                throw;
            }
        }
        async Task SendUsingNewModel(IPipe<ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            IPipe<ConnectionContext> connectionPipe = Pipe.ExecuteAsync<ConnectionContext>(async connectionContext =>
            {
                try
                {
                    if (_log.IsDebugEnabled)
                        _log.DebugFormat("Creating model: {0}", connectionContext.HostSettings.ToDebugString());

                    var model = await connectionContext.CreateModel().ConfigureAwait(false);

                    EventHandler<ShutdownEventArgs> modelShutdown = null;
                    modelShutdown = (obj, reason) =>
                    {
                        model.ModelShutdown -= modelShutdown;

                        Interlocked.CompareExchange(ref _scope, null, scope);

                        scope.Shutdown(reason.ReplyText);
                    };

                    model.ModelShutdown += modelShutdown;

                    var modelContext = new RabbitMqModelContext(connectionContext, model, _cacheTaskScope, _modelSettings);

                    scope.Created(modelContext);
                }
                catch (Exception ex)
                {
                    Interlocked.CompareExchange(ref _scope, null, scope);

                    scope.CreateFaulted(ex);

                    throw;
                }

                await SendUsingExistingModel(modelPipe, scope, cancellationToken).ConfigureAwait(false);
            });

            try
            {
                await _connectionCache.Send(connectionPipe, _cacheTaskScope.StoppedToken).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                    _log.Debug("The connection threw an exception", exception);

                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.CreateFaulted(exception);

                throw;
            }
        }
        async Task SendUsingExistingModel(IPipe<ModelContext> modelPipe, ModelScope scope, CancellationToken cancellationToken)
        {
            try
            {
                using (var context = await scope.Attach(cancellationToken).ConfigureAwait(false))
                {
//                    if (_log.IsDebugEnabled)
//                        _log.DebugFormat("Using model: {0}", ((ModelContext)context).ConnectionContext.HostSettings.ToDebugString());

                    await modelPipe.Send(context).ConfigureAwait(false);
                }
            }
            catch (Exception exception)
            {
                if (_log.IsDebugEnabled)
                    _log.Debug("The model usage threw an exception", exception);

                Interlocked.CompareExchange(ref _scope, null, scope);

                scope.CreateFaulted(exception);

                throw;
            }
        }