public object Deserialize(
            BsonReader bsonReader,
            Type classType
        )
        {
            // peek at the discriminator (if present) to see what class to create an instance for
            var discriminator = bsonReader.FindString("_t");
            if (discriminator != null) {
                var actualType = BsonClassMap.LookupTypeByDiscriminator(classType, discriminator);
                if (!classType.IsAssignableFrom(actualType)) {
                    string message = string.Format("Actual type {0} is not assignable to expected type {1}", actualType.FullName, classType.FullName);
                    throw new FileFormatException(message);
                }
                classType = actualType;
            }
            var classMap = BsonClassMap.LookupClassMap(classType);
            if (classMap.IsAnonymous) {
                throw new InvalidOperationException("Anonymous classes cannot be deserialized");
            }
            var obj = Activator.CreateInstance(classType);

            var missingElementPropertyMaps = new List<BsonPropertyMap>(classMap.PropertyMaps); // make a copy!
            bsonReader.ReadStartDocument();
            BsonType bsonType;
            string elementName;
            while (bsonReader.HasElement(out bsonType, out elementName)) {
                if (elementName == "_t") {
                    bsonReader.ReadString("_t"); // skip over discriminator
                    continue;
                }

                var propertyMap = classMap.GetPropertyMapForElement(elementName);
                if (propertyMap != null) {
                    propertyMap.PropertySerializer.DeserializeProperty(bsonReader, obj, propertyMap);
                    missingElementPropertyMaps.Remove(propertyMap);
                } else {
                    if (classMap.IgnoreExtraElements) {
                        bsonReader.SkipElement();
                    } else {
                        string message = string.Format("Unexpected element: {0}", elementName);
                        throw new FileFormatException(message);
                    }
                }
            }
            bsonReader.ReadEndDocument();

            foreach (var propertyMap in missingElementPropertyMaps) {
                if (propertyMap.IsRequired) {
                    string message = string.Format("Required element is missing: {0}", propertyMap.ElementName);
                    throw new BsonSerializationException(message);
                }

                if (propertyMap.HasDefaultValue) {
                    propertyMap.ApplyDefaultValue(obj);
                }
            }

            return obj;
        }
 public void DeserializeProperty(
     BsonReader bsonReader,
     object obj,
     BsonPropertyMap propertyMap
 )
 {
     BsonType bsonType = bsonReader.PeekBsonType();
     TimeSpan value;
     if (bsonType == BsonType.Int64) {
         value = new TimeSpan(bsonReader.ReadInt64(propertyMap.ElementName));
     } else if (bsonType == BsonType.Document) {
         bsonReader.ReadDocumentName(propertyMap.ElementName);
         bsonReader.ReadStartDocument();
         bsonReader.VerifyString("_t", typeof(TimeSpan).FullName);
         value = TimeSpan.Parse(bsonReader.ReadString("v"));
         bsonReader.ReadEndDocument();
     } else {
         throw new FileFormatException("Element is not valid System.TimeSpan");
     }
     propertyMap.Setter(obj, value);
 }
 public void DeserializeProperty(
     BsonReader bsonReader,
     object obj,
     BsonPropertyMap propertyMap
 )
 {
     var bsonType = bsonReader.PeekBsonType();
     BsonString value;
     if (bsonType == BsonType.Null) {
         bsonReader.ReadNull(propertyMap.ElementName);
         value = null;
     } else {
         value = BsonString.Create(bsonReader.ReadString(propertyMap.ElementName));
     }
     propertyMap.Setter(obj, value);
 }
 public void DeserializeProperty(
     BsonReader bsonReader,
     object obj,
     BsonPropertyMap propertyMap
 )
 {
     bsonReader.ReadDocumentName(propertyMap.ElementName);
     bsonReader.ReadStartDocument();
     bsonReader.VerifyString("_t", typeof(Decimal).FullName);
     var value = XmlConvert.ToDecimal(bsonReader.ReadString("v"));
     bsonReader.ReadEndDocument();
     propertyMap.Setter(obj, value);
 }
 public void DeserializeProperty(
     BsonReader bsonReader,
     object obj,
     BsonPropertyMap propertyMap
 )
 {
     BsonType bsonType = bsonReader.PeekBsonType();
     DateTimeOffset value;
     if (bsonType == BsonType.Array) {
         bsonReader.ReadArrayName(propertyMap.ElementName);
         bsonReader.ReadStartDocument();
         var dateTime = new DateTime(bsonReader.ReadInt64("0"));
         var offset = new TimeSpan(bsonReader.ReadInt64("1"));
         bsonReader.ReadEndDocument();
         value = new DateTimeOffset(dateTime, offset);
     } else if (bsonType == BsonType.Document) {
         bsonReader.ReadDocumentName(propertyMap.ElementName);
         bsonReader.ReadStartDocument();
         bsonReader.VerifyString("_t", typeof(DateTimeOffset).FullName);
         var dateTime = DateTime.Parse(bsonReader.ReadString("dt")); // Kind = DateTimeKind.Unspecified
         var offset = TimeSpan.Parse(bsonReader.ReadString("o"));
         bsonReader.ReadEndDocument();
         value = new DateTimeOffset(dateTime, offset);
     } else {
         throw new FileFormatException("Element is not valid System.DateTimeOffset");
     }
     propertyMap.Setter(obj, value);
 }
 public void DeserializeProperty(
     BsonReader bsonReader,
     object obj,
     BsonPropertyMap propertyMap
 )
 {
     bsonReader.ReadDocumentName(propertyMap.ElementName);
     bsonReader.ReadStartDocument();
     bsonReader.VerifyString("_t", typeof(CultureInfo).FullName);
     var value = new CultureInfo(bsonReader.ReadString("v"));
     bsonReader.ReadEndDocument();
     propertyMap.Setter(obj, value);
 }
 public void DeserializeProperty(
     BsonReader bsonReader,
     object obj,
     BsonPropertyMap propertyMap
 )
 {
     BsonType bsonType = bsonReader.PeekBsonType();
     char value;
     if (bsonType == BsonType.String) {
         value = (char) bsonReader.ReadString(propertyMap.ElementName)[0];
     } else if (bsonType == BsonType.Document) {
         bsonReader.ReadDocumentName(propertyMap.ElementName);
         bsonReader.ReadStartDocument();
         bsonReader.VerifyString("_t", typeof(char).FullName);
         value = bsonReader.ReadString("v")[0];
         bsonReader.ReadEndDocument();
     } else {
         throw new FileFormatException("Element is not valid System.Char");
     }
     propertyMap.Setter(obj, value);
 }
 public void DeserializeProperty(
     BsonReader bsonReader,
     object obj,
     BsonPropertyMap propertyMap
 )
 {
     var employee = (Employee) obj;
     employee.DateOfBirth = DateTime.Parse(bsonReader.ReadString(propertyMap.ElementName));
 }