#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
        public void SendMessagesInBothDirections(ChannelExchange[] cases)
#pragma warning restore xUnit1026 // Theory methods should use all of their parameters
        {
            var serverSentMessageHashes     = new List <List <byte[]> >();
            var serverReceivedMessageHashes = new List <List <byte[]> >();
            var clientSentMessageHashes     = new List <List <byte[]> >();
            var clientReceivedMessageHashes = new List <List <byte[]> >();

            async Task HandleChannelAsync(ITransportChannel c, int[] send, List <byte[]> received, List <byte[]> sent)
            {
                Log.Info("Handling channel {0}", c.Id);
                var receiveTask = TaskRunner.RunInBackground(
                    async() =>
                {
                    while (true)
                    {
                        var receivedMsg = await c.TryReceiveMessageAsync().ConfigureAwait(false);
                        if (!receivedMsg.HasValue)
                        {
                            break;
                        }
                        lock (Md5)
                        {
                            received.Add(Md5.ComputeHash(receivedMsg.Value));
                        }
                    }
                });

                foreach (var length in send)
                {
                    var msg = TestsSuite.Random.GetRandomBytes(length);
                    await c.SendMessageAsync(msg).ConfigureAwait(false);

                    lock (Md5)
                    {
                        sent.Add(Md5.ComputeHash(msg));
                    }
                }
                c.Out.TryComplete();
                await receiveTask.ConfigureAwait(false);

                Log.Info("Channel handling completed {0}. Received {1} messages.", c.Id, received.Count);
            }

            ITransportConnection clientConnection = null;
            ITransportConnection serverConnection = null;
            var serverTask = TaskRunner.RunInBackground(
                async() =>
            {
                await Server.StartAsync().ConfigureAwait(false);
                serverConnection = await Server.In.ReadAsync().ConfigureAwait(false);
                Log.Info("Server connection created");
                var channelTasks = new List <Task>();
                foreach (var channelExchange in cases)
                {
                    var channel = await serverConnection.CreateChannelAsync().ConfigureAwait(false);
                    Log.Info("Server channel created");
                    var rec  = new List <byte[]>();
                    var sent = new List <byte[]>();
                    clientReceivedMessageHashes.Add(rec);
                    clientSentMessageHashes.Add(sent);
                    channelTasks.Add(TaskRunner.RunInBackground(() =>
                                                                HandleChannelAsync(channel, channelExchange.ClientMessageLengths, rec, sent)));
                }
                await Task.WhenAll(channelTasks).ConfigureAwait(false);
            });

            var clientTask = TaskRunner.RunInBackground(
                async() =>
            {
                clientConnection = await Client.ConnectAsync(BrokerWorkingDir).ConfigureAwait(false);
                Log.Info("Client connection created");
                var channelTasks = new List <Task>();
                foreach (var channelExchange in cases)
                {
                    var channel = await clientConnection.IncomingChannels.ReadAsync().ConfigureAwait(false);
                    Log.Info("Client channel received");
                    var rec  = new List <byte[]>();
                    var sent = new List <byte[]>();
                    serverReceivedMessageHashes.Add(rec);
                    serverSentMessageHashes.Add(sent);
                    channelTasks.Add(TaskRunner.RunInBackground(() => HandleChannelAsync(channel, channelExchange.ServerMessageLengths, rec, sent)));
                }
                await Task.WhenAll(channelTasks).ConfigureAwait(false);
            });

            Should.CompleteIn(Task.WhenAll(serverTask, clientTask), Timeout30Sec);
            Should.CompleteIn(clientConnection.CompleteAsync(), Timeout1Sec);
            Should.CompleteIn(serverConnection.CompleteAsync(), Timeout1Sec);

            Log.Debug("Tasks completed");
            serverReceivedMessageHashes.Count.ShouldBe(cases.Length);
            serverSentMessageHashes.Count.ShouldBe(cases.Length);
            clientReceivedMessageHashes.Count.ShouldBe(cases.Length);
            clientSentMessageHashes.Count.ShouldBe(cases.Length);
            for (int i = 0; i < serverReceivedMessageHashes.Count; i++)
            {
                serverReceivedMessageHashes[i].Count.ShouldBe(clientSentMessageHashes[i].Count);
                for (int j = 0; j < serverReceivedMessageHashes[i].Count; j++)
                {
                    serverReceivedMessageHashes[i][j].ShouldBe(clientSentMessageHashes[i][j]);
                }
            }
            for (int i = 0; i < clientReceivedMessageHashes.Count; i++)
            {
                clientReceivedMessageHashes[i].Count.ShouldBe(serverSentMessageHashes[i].Count);
                for (int j = 0; j < clientReceivedMessageHashes[i].Count; j++)
                {
                    clientReceivedMessageHashes[i][j].ShouldBe(serverSentMessageHashes[i][j]);
                }
            }
        }