public MessageSequence <TMessage> Complete <TMessage>()
        {
            _logger.LogDebug($"Message Sequence for '{_globalMessageId}' completes with '{typeof(TMessage).Name}'.");
            var sequenceDef = _repository.GetOrCreate(_globalMessageId);

            var messageTcs = new TaskCompletionSource <TMessage>();
            var sequence   = new MessageSequence <TMessage>
            {
                Task = messageTcs.Task
            };

            sequenceDef.TaskCompletionSource.Task.ContinueWith(tObj =>
            {
                UpdateSequenceFinalState(sequence);
                messageTcs.TrySetResult((TMessage)tObj.Result);
            });

            Func <TMessage, TMessageContext, Task> func = (message, context) =>
            {
                Task
                .WhenAll(sequenceDef.State.HandlerTasks)
                .ContinueWith(t => sequenceDef.TaskCompletionSource.TrySetResult(message));
                return(Task.FromResult(true));
            };

            var bindTask = _chainTopology.BindToExchange <TMessage>(_globalMessageId);

            _dispatcher.AddMessageHandler(_globalMessageId, func);

            Task
            .WhenAll(bindTask)
            .ContinueWith(t => _publishAsync())
            .Unwrap()
            .Wait();

            Timer timeoutTimer = null;

            timeoutTimer = new Timer(state =>
            {
                timeoutTimer?.Dispose();
                var seq = _repository.Get(_globalMessageId);
                if (seq != null)
                {
                    seq.State.Aborted = true;
                    _repository.Update(seq);
                    UpdateSequenceFinalState(sequence);
                }

                messageTcs.TrySetException(
                    new TimeoutException(
                        $"Unable to complete sequence {_globalMessageId} in {_mainCfg.RequestTimeout.ToString("g")}. Operation Timed out."));
            }, null, _mainCfg.RequestTimeout, new TimeSpan(-1));

            return(sequence);
        }
        public void AddMessageHandler <TMessage, TMessageContext>(Guid globalMessageId, Func <TMessage, TMessageContext, Task> func, StepOption configuration) where TMessageContext : IMessageContext
        {
            var sequence = _sequenceRepository.GetOrCreate(globalMessageId);

            sequence.StepDefinitions.Add(new StepDefinition
            {
                Handler         = (o, context) => func((TMessage)o, (TMessageContext)context),
                Type            = typeof(TMessage),
                Optional        = configuration?.Optional ?? false,
                AbortsExecution = configuration?.AbortsExecution ?? false
            });
            _sequenceRepository.Update(sequence);
        }