// private static methods
        private byte[] CombineCommandMessageSectionsIntoSingleDocument(Stream stream)
        {
            using (var inputStream = new BsonStreamAdapter(stream, ownsStream: false))
                using (var memoryStream = new MemoryStream())
                    using (var outputStream = new BsonStreamAdapter(memoryStream, ownsStream: false))
                    {
                        var messageStartPosition = inputStream.Position;
                        var messageLength        = inputStream.ReadInt32();
                        var messageEndPosition   = messageStartPosition + messageLength;
                        var requestId            = inputStream.ReadInt32();
                        var responseTo           = inputStream.ReadInt32();
                        var opcode = inputStream.ReadInt32();
                        var flags  = (OpMsgFlags)inputStream.ReadInt32();
                        if (flags.HasFlag(OpMsgFlags.ChecksumPresent))
                        {
                            messageEndPosition -= 4; // ignore checksum
                        }

                        CopyType0Section(inputStream, outputStream);
                        outputStream.Position -= 1;
                        while (inputStream.Position < messageEndPosition)
                        {
                            CopyType1Section(inputStream, outputStream);
                        }
                        outputStream.WriteByte(0);
                        outputStream.BackpatchSize(0);

                        return(memoryStream.ToArray());
                    }
        }
 private byte[] CreateType1SectionBytes(Type1CommandMessageSection <BsonDocument> section)
 {
     using (var memoryStream = new MemoryStream())
         using (var stream = new BsonStreamAdapter(memoryStream))
             using (var writer = new BsonBinaryWriter(stream))
             {
                 stream.WriteByte(1);
                 var payloadStartPosition = stream.Position;
                 stream.WriteInt32(0); // size
                 stream.WriteCString(section.Identifier);
                 var context = BsonSerializationContext.CreateRoot(writer);
                 var batch   = section.Documents;
                 for (var i = 0; i < batch.Count; i++)
                 {
                     var document = batch.Items[batch.Offset + i];
                     BsonDocumentSerializer.Instance.Serialize(context, document);
                 }
                 stream.BackpatchSize(payloadStartPosition);
                 return(memoryStream.ToArray());
             }
 }
        public void BackpatchSize_should_backpatch_the_size(
            [Values(0, 1, 5)]
            int startPosition)
        {
            var bytes         = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            var length        = bytes.Length - startPosition;
            var expectedBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            Array.Copy(BitConverter.GetBytes(length), 0, expectedBytes, startPosition, 4);

            using (var memoryStream = new MemoryStream())
                using (var stream = new BsonStreamAdapter(memoryStream))
                {
                    stream.WriteBytes(bytes, 0, bytes.Length);
                    var position = stream.Position;

                    stream.BackpatchSize(startPosition);

                    memoryStream.ToArray().Should().Equal(expectedBytes);
                    stream.Position.Should().Be(position);
                }
        }