/// <summary>
        /// Writes message to the writer
        /// </summary>
        /// <param name="obj">Message to write</param>
        /// <param name="writer">Writer used to write the message</param>
        void IStreamingCodec <MapInputWithControlMessage <TMapInput> > .Write(MapInputWithControlMessage <TMapInput> obj,
                                                                              IDataWriter writer)
        {
            switch (obj.ControlMessage)
            {
            case MapControlMessage.AnotherRound:
                writer.Write(new byte[] { 0 }, 0, 1);
                _baseCodec.Write(obj.Message, writer);
                break;

            case MapControlMessage.Stop:
                writer.Write(new byte[] { 1 }, 0, 1);
                break;
            }
        }
        /// <summary>
        /// Dechunks the message
        /// </summary>
        /// <param name="pipelineMessage">Message chunks</param>
        /// <returns>Single aggregated message</returns>
        MapInputWithControlMessage <TMapInput> IPipelineDataConverter <MapInputWithControlMessage <TMapInput> > .FullMessage(
            List <PipelineMessage <MapInputWithControlMessage <TMapInput> > > pipelineMessage)
        {
            if (pipelineMessage.Count == 1)
            {
                return(pipelineMessage[0].Data);
            }

            var baseMessageChunks =
                pipelineMessage.Select(x => new PipelineMessage <TMapInput>(x.Data.Message, false)).ToList();

            MapInputWithControlMessage <TMapInput> combinedMessage =
                new MapInputWithControlMessage <TMapInput>(_basePipelineDataConverter.FullMessage(baseMessageChunks),
                                                           pipelineMessage[0].Data.ControlMessage);

            return(combinedMessage);
        }
        /// <summary>
        /// Writes message asynchronously to the writer
        /// </summary>
        /// <param name="obj">Message to write</param>
        /// <param name="writer">Writer used to write the message</param>
        /// <param name="token">Cancellation token</param>
        async Task IStreamingCodec <MapInputWithControlMessage <TMapInput> > .WriteAsync(
            MapInputWithControlMessage <TMapInput> obj, IDataWriter writer, CancellationToken token)
        {
            switch (obj.ControlMessage)
            {
            case MapControlMessage.AnotherRound:
                await writer.WriteAsync(new byte[] { 0 }, 0, 1, token);

                await _baseCodec.WriteAsync(obj.Message, writer, token);

                break;

            case MapControlMessage.Stop:
                writer.Write(new byte[] { 1 }, 0, 1);
                break;
            }
        }
        IPipelineDataConverter <MapInputWithControlMessage <TMapInput> > .PipelineMessage(
            MapInputWithControlMessage <TMapInput> message)
        {
            List <PipelineMessage <MapInputWithControlMessage <TMapInput> > > messageChunks =
                new List <PipelineMessage <MapInputWithControlMessage <TMapInput> > >();

            if (message.ControlMessage == MapControlMessage.Stop)
            {
                messageChunks.Add(new PipelineMessage <MapInputWithControlMessage <TMapInput> >(message, true));
                return(messageChunks);
            }

            var baseMessageChunks = _basePipelineDataConverter.PipelineMessage(message.Message);

            messageChunks.AddRange(
                baseMessageChunks.Select(
                    t =>
                    new PipelineMessage <MapInputWithControlMessage <TMapInput> >(
                        new MapInputWithControlMessage <TMapInput>(t.Data, message.ControlMessage), t.IsLast)));

            return(messageChunks);
        }