Introduce a closed type system for BSON documents and use it pervasively in the core of the driver, in preference to the open-typed Document class that is used now.
Introduce a BsonDocumentReader implementation of BsonReader and a BsonDocument implementation of BsonWriter. This allows for easy conversion from any type with a Codec to and from a BsonDocument.
This also means that clients of the core driver don't have to pass a separate encoder/decoder to operations that take or receive BsonDocument instances, as operations can just use the built-in BsonDocument Codec (which does not need to be extensible since the type system is closed)
To handle the case where a client wants to pass an object to an operation without paying the cost of converting to BsonDocument, provide a BsonDocumentWrapper sub-class of BsonDocument that is constructed with an instance of T and an Encoder<T>. When the operation serializes it to the wire, it will just use that Encoder to do it.