/// <summary>
        /// Serializes a value.
        /// </summary>
        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
        /// <param name="bsonWriter">The BsonWriter.</param>
        /// <param name="value">The object.</param>
        /// <param name="configurator">The serialization context configurator.</param>
        public static void Serialize <TNominalType>(
            BsonWriter bsonWriter,
            TNominalType value,
            Action <BsonSerializationContext.Builder> configurator = null)
        {
            var serializer = LookupSerializer <TNominalType>();
            var context    = BsonSerializationContext.CreateRoot <TNominalType>(bsonWriter, configurator);

            serializer.Serialize(context, value);
        }
        /// <summary>
        /// Serializes a value.
        /// </summary>
        /// <param name="bsonWriter">The BsonWriter.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="value">The object.</param>
        /// <param name="configurator">The serialization context configurator.</param>
        public static void Serialize(
            BsonWriter bsonWriter,
            Type nominalType,
            object value,
            Action <BsonSerializationContext.Builder> configurator = null)
        {
            var serializer = LookupSerializer(nominalType);
            var context    = BsonSerializationContext.CreateRoot(bsonWriter, nominalType, configurator);

            serializer.Serialize(context, value);
        }
        /// <summary>
        /// Serializes a value.
        /// </summary>
        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
        /// <param name="bsonWriter">The BsonWriter.</param>
        /// <param name="value">The object.</param>
        /// <param name="configurator">The serialization context configurator.</param>
        /// <param name="args">The serialization args.</param>
        public static void Serialize <TNominalType>(
            IBsonWriter bsonWriter,
            TNominalType value,
            Action <BsonSerializationContext.Builder> configurator = null,
            BsonSerializationArgs args = default(BsonSerializationArgs))
        {
            args.SetOrValidateNominalType(typeof(TNominalType), "<TNominalType>");
            var serializer = LookupSerializer <TNominalType>();
            var context    = BsonSerializationContext.CreateRoot(bsonWriter, configurator);

            serializer.Serialize(context, args, value);
        }
        /// <summary>
        /// Serializes a value.
        /// </summary>
        /// <param name="bsonWriter">The BsonWriter.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="value">The object.</param>
        /// <param name="configurator">The serialization context configurator.</param>
        /// <param name="args">The serialization args.</param>
        public static void Serialize(
            IBsonWriter bsonWriter,
            Type nominalType,
            object value,
            Action <BsonSerializationContext.Builder> configurator = null,
            BsonSerializationArgs args = default(BsonSerializationArgs))
        {
            args.SetOrValidateNominalType(nominalType, "nominalType");
            var serializer = LookupSerializer(nominalType);
            var context    = BsonSerializationContext.CreateRoot(bsonWriter, configurator);

            serializer.Serialize(context, args, value);
        }
        /// <summary>
        /// Serializes the value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The serialized value.</returns>
        public BsonValue SerializeValue(object value)
        {
            var tempDocument = new BsonDocument();

            using (var bsonWriter = new BsonDocumentWriter(tempDocument))
            {
                var context = BsonSerializationContext.CreateRoot <BsonDocument>(bsonWriter);
                bsonWriter.WriteStartDocument();
                bsonWriter.WriteName("value");
                context.SerializeWithChildContext(_serializer, value);
                bsonWriter.WriteEndDocument();
                return(tempDocument[0]);
            }
        }
        /// <summary>
        /// Converts a value to a BsonValue by serializing it.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="serializer">The serializer.</param>
        /// <param name="value">The value.</param>
        /// <returns>The serialized value.</returns>
        public static BsonValue ToBsonValue <TValue>(this IBsonSerializer <TValue> serializer, TValue value)
        {
            var document = new BsonDocument();

            using (var writer = new BsonDocumentWriter(document))
            {
                var context = BsonSerializationContext.CreateRoot(writer);
                writer.WriteStartDocument();
                writer.WriteName("x");
                serializer.Serialize(context, value);
                writer.WriteEndDocument();
            }
            return(document[0]);
        }
        /// <summary>
        /// Serializes the values.
        /// </summary>
        /// <param name="values">The values.</param>
        /// <returns>The serialized values.</returns>
        public BsonArray SerializeValues(IEnumerable values)
        {
            var tempDocument = new BsonDocument();

            using (var bsonWriter = new BsonDocumentWriter(tempDocument))
            {
                var context = BsonSerializationContext.CreateRoot <BsonDocument>(bsonWriter);
                bsonWriter.WriteStartDocument();
                bsonWriter.WriteName("values");
                bsonWriter.WriteStartArray();
                foreach (var value in values)
                {
                    context.SerializeWithChildContext(_serializer, value);
                }
                bsonWriter.WriteEndArray();
                bsonWriter.WriteEndDocument();

                return(tempDocument[0].AsBsonArray);
            }
        }