Case Classes, Codecs, etc. 

a CodecBson instance is both an encoder and a decoder - it implements both EncodeBson and DecodeBson. the main use for them is to define encoding and decoding of a case class simultaneously.

case class ThreePart(x: String, y: List[Int], z: DateTime)
implicit val codecThreePart =
  bsonCaseCodec3(ThreePart.apply, ThreePart.unapply)("x", "y", "z")
val example = ThreePart("hi", List(4, 3), z = DateTime.now())
val dbo = example.asBson
dbo.keySet === Set("x", "y", "z")
dbo.decode[ThreePart] === \/-(example)