// protected methods
        /// <summary>
        /// Deserializes a value.
        /// </summary>
        /// <param name="context">The deserialization context.</param>
        /// <param name="args">The deserialization args.</param>
        /// <returns>The value.</returns>
        protected override GeoJsonBoundingBox <TCoordinates> DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var bsonReader = context.Reader;

            var flattenedArray = BsonArraySerializer.Instance.Deserialize(context);

            if ((flattenedArray.Count % 2) != 0)
            {
                throw new FormatException("Bounding box array does not have an even number of values.");
            }
            var half = flattenedArray.Count / 2;

            // create a dummy document with a min and a max and then deserialize the min and max coordinates from there
            var document = new BsonDocument
            {
                { "min", new BsonArray(flattenedArray.Take(half)) },
                { "max", new BsonArray(flattenedArray.Skip(half)) }
            };

            using (var documentReader = new BsonDocumentReader(document))
            {
                var documentContext = BsonDeserializationContext.CreateRoot(documentReader);
                documentReader.ReadStartDocument();
                documentReader.ReadName("min");
                var min = _coordinatesSerializer.Deserialize(documentContext);
                documentReader.ReadName("max");
                var max = _coordinatesSerializer.Deserialize(documentContext);
                documentReader.ReadEndDocument();

                return(new GeoJsonBoundingBox <TCoordinates>(min, max));
            }
        }
        private object DeserializeKeyString(string keyString)
        {
            var keyDocument = new BsonDocument("k", keyString);

            using (var keyReader = new BsonDocumentReader(keyDocument))
            {
                var context = BsonDeserializationContext.CreateRoot(keyReader);
                keyReader.ReadStartDocument();
                keyReader.ReadName("k");
                var key = _keySerializer.Deserialize(context);
                keyReader.ReadEndDocument();
                return(key);
            }
        }
        /// <summary>
        /// Deserializes the value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The deserialized value.</returns>
        public object DeserializeValue(BsonValue value)
        {
            var tempDocument = new BsonDocument("value", value);

            using (var reader = new BsonDocumentReader(tempDocument))
            {
                var context = BsonDeserializationContext.CreateRoot <BsonDocument>(reader);
                reader.ReadStartDocument();
                reader.ReadName("value");
                var deserializedValue = context.DeserializeWithChildContext(_serializer);
                reader.ReadEndDocument();
                return(deserializedValue);
            }
        }
        // public methods
        /// <summary>
        /// Gets an enumerator for the result objects.
        /// </summary>
        /// <returns>An enumerator for the result objects.</returns>
        public IEnumerator <TResult> GetEnumerator()
        {
            foreach (var value in _source)
            {
                var document = new BsonDocument("_v", value);
                using (var bsonReader = new BsonDocumentReader(document))
                {
                    var context = BsonDeserializationContext.CreateRoot(bsonReader);
                    bsonReader.ReadStartDocument();
                    bsonReader.ReadName("_v");
                    yield return((TResult)_serializationInfo.Serializer.Deserialize(context));

                    bsonReader.ReadEndDocument();
                }
            }
        }