/// <summary>
        /// Gets the item serialization info.
        /// </summary>
        /// <param name="methodName">Name of the method.</param>
        /// <param name="serializationInfo">The serialization info.</param>
        /// <returns>The item BsonSerializationInfo for the expression.</returns>
        public BsonSerializationInfo GetItemSerializationInfo(string methodName, BsonSerializationInfo serializationInfo)
        {
            var arraySerializer = serializationInfo.Serializer as IBsonArraySerializer;
            if (arraySerializer != null)
            {
                var itemSerializationInfo = arraySerializer.GetItemSerializationInfo();
                if (itemSerializationInfo != null)
                {
                    var arrayOptions = serializationInfo.SerializationOptions as ArraySerializationOptions;
                    if (arrayOptions != null)
                    {
                        var itemSerializationOptions = arrayOptions.ItemSerializationOptions;
                        return new BsonSerializationInfo(
                            itemSerializationInfo.ElementName,
                            itemSerializationInfo.Serializer,
                            itemSerializationInfo.NominalType,
                            itemSerializationOptions);
                    }

                    return itemSerializationInfo;
                }
            }

            string message = string.Format("{0} requires that the serializer specified for {1} support items by implementing {2} and returning a non-null result. {3} is the current serializer.",
                methodName,
                serializationInfo.ElementName,
                typeof(IBsonArraySerializer),
                serializationInfo.Serializer.GetType());
            throw new NotSupportedException(message);
        }
        // protected methods
        /// <summary>
        /// Registers a member.
        /// </summary>
        /// <param name="memberName">The member name.</param>
        /// <param name="elementName">The element name.</param>
        /// <param name="serializer">The serializer.</param>
        /// <param name="nominalType">The nominal type.</param>
        /// <param name="serializationOptions">The serialization options.</param>
        protected void RegisterMember(string memberName, string elementName, IBsonSerializer serializer, Type nominalType, IBsonSerializationOptions serializationOptions)
        {
            if (memberName == null)
            {
                throw new ArgumentNullException("memberName");
            }
            if (elementName == null)
            {
                throw new ArgumentNullException("elementName");
            }
            if (serializer == null)
            {
                throw new ArgumentNullException("serializer");
            }
            if (nominalType == null)
            {
                throw new ArgumentNullException("nominalType");
            }

            var info = new BsonSerializationInfo(elementName, serializer, nominalType, serializationOptions);

            _memberSerializationInfo.Add(memberName, info);
        }
 /// <summary>
 /// Registers a serializer with the given expression.
 /// </summary>
 /// <param name="node">The expression.</param>
 /// <param name="serializer">The serializer.</param>
 public void RegisterExpressionSerializer(Expression node, IBsonSerializer serializer)
 {
     _serializationInfoCache[node] = new BsonSerializationInfo(
         null,
         serializer,
         node.Type,
         serializer.GetDefaultSerializationOptions());
 }
 /// <summary>
 /// Serializes the values given the serialization information.
 /// </summary>
 /// <param name="serializationInfo">The serialization info.</param>
 /// <param name="values">The values.</param>
 /// <returns>A BsonArray representing the values serialized using the serializer.</returns>
 public BsonArray SerializeValues(BsonSerializationInfo serializationInfo, IEnumerable values)
 {
     return serializationInfo.SerializeValues(values);
 }
 /// <summary>
 /// Serializes the value given the serialization information.
 /// </summary>
 /// <param name="serializationInfo">The serialization info.</param>
 /// <param name="value">The value.</param>
 /// <returns>A BsonValue representing the value serialized using the serializer.</returns>
 public BsonValue SerializeValue(BsonSerializationInfo serializationInfo, object value)
 {
     return serializationInfo.SerializeValue(value);
 }