public void WriteMessage_should_invoke_encoding_post_processor()
        {
            var stream   = new MemoryStream();
            var subject  = CreateSubject(stream);
            var command  = BsonDocument.Parse("{ command : \"x\", writeConcern : { w : 0 } }");
            var section  = new Type0CommandMessageSection <BsonDocument>(command, BsonDocumentSerializer.Instance);
            var sections = new CommandMessageSection[] { section };
            var message  = CreateMessage(sections: sections, moreToCome: true);

            message.PostWriteAction = encoder =>
            {
                encoder.ChangeWriteConcernFromW0ToW1();
            };

            subject.WriteMessage(message);

            stream.Position = 0;
            var rehydratedMessage = subject.ReadMessage();

            rehydratedMessage.MoreToCome.Should().BeFalse();
            var rehydratedType0Section = rehydratedMessage.Sections.OfType <Type0CommandMessageSection <RawBsonDocument> >().Single();
            var rehyrdatedCommand      = rehydratedType0Section.Document;

            rehyrdatedCommand["writeConcern"]["w"].Should().Be(1);

            // assert that the original message was altered only as expected
            message.MoreToCome.Should().BeFalse(); // was true before PostWriteAction
            var originalCommand = message.Sections.OfType <Type0CommandMessageSection <BsonDocument> >().Single().Document;

            originalCommand["writeConcern"]["w"].Should().Be(0); // unchanged
        }
        private BsonDocument CreateSectionDocument(CommandMessageSection section)
        {
            switch (section.PayloadType)
            {
            case PayloadType.Type0:
                return(CreateType0SectionDocument((Type0CommandMessageSection <BsonDocument>)section));

            case PayloadType.Type1:
                return(CreateType1SectionDocument((Type1CommandMessageSection <BsonDocument>)section));

            default:
                throw new ArgumentException($"Invalid payload type: {section.PayloadType}.", nameof(section));
            }
        }
        private void WriteSection(BsonBinaryWriter writer, CommandMessageSection section, long messageStartPosition)
        {
            writer.BsonStream.WriteByte((byte)section.PayloadType);

            switch (section.PayloadType)
            {
            case PayloadType.Type0:
                WriteType0Section(writer, (Type0CommandMessageSection)section);
                break;

            case PayloadType.Type1:
                WriteType1Section(writer, (Type1CommandMessageSection)section, messageStartPosition);
                break;

            default:
                throw new ArgumentException("Invalid payload type.", nameof(section));
            }
        }
        private void WriteSection(IBsonWriter writer, CommandMessageSection section)
        {
            writer.WriteStartDocument();
            writer.WriteInt32("payloadType", (int)section.PayloadType);

            switch (section.PayloadType)
            {
            case PayloadType.Type0:
                WriteType0Section(writer, (Type0CommandMessageSection)section);
                break;

            case PayloadType.Type1:
                WriteType1Section(writer, (Type1CommandMessageSection)section);
                break;

            default:
                throw new ArgumentException($"Invalid payload type: {section.PayloadType}.");
            }

            writer.WriteEndDocument();
        }