/**
         * This will block the executing thread until inputStream is closed
         */
        public void Start(Stream inputStream, TextWriter writer)
        {
            var channelClosedCancelationTokenSource = new CancellationTokenSource();

            try
            {
                if (IsLoggingEnabled)
                {
                    InitialiseLogger();
                }

                _channel.Init(inputStream, writer);

                _messageDispatcher.Init(_dispatchMessagesBufferBlock, _channel);
                _requestExecutor.Init(_requestHandlers, _dispatchMessagesBufferBlock);
                _responseHandlerExecutor.Init(_responseHandlers, _dispatchMessagesBufferBlock);

                var messageDispatcherTask = _messageDispatcher.StartAsync(channelClosedCancelationTokenSource.Token);

                Task.Run(() =>
                {
                    while (_channel.IsOpen)
                    {
                        var channelReadResult = _channel.Read();

                        foreach (var request in channelReadResult.Requests)
                        {
                            _requestExecutor.ExecuteAsync(request, channelClosedCancelationTokenSource.Token);
                        }
                        foreach (var response in channelReadResult.Responses)
                        {
                            _responseHandlerExecutor.ExecuteAsync(response, channelClosedCancelationTokenSource.Token);
                        }
                    }
                    channelClosedCancelationTokenSource.Cancel();
                });

                messageDispatcherTask.Wait(); //if anything goes wrong this is where the exceptions come from
            }
            catch (AggregateException ex)
            {
                Console.Error.WriteLine(ex.Message);
                if (IsLoggingEnabled)
                {
                    var flattenedAggregateException = ex.Flatten();

                    foreach (var exception in flattenedAggregateException.InnerExceptions)
                    {
                        Log.Error(exception, string.Empty);
                    }
                }
                else
                {
                    throw;
                }
            }
        }