diff --git a/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/bsoncore.go b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/bsoncore.go
new file mode 100644
index 0000000..8d2946a
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/bsoncore.go
@@ -0,0 +1,791 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+// Package bsoncore contains functions that can be used to encode and decode BSON
+// elements and values to or from a slice of bytes. These functions are aimed at
+// allowing low level manipulation of BSON and can be used to build a higher
+// level BSON library.
+//
+// The Read* functions within this package return the values of the element and
+// a boolean indicating if the values are valid. A boolean was used instead of
+// an error because any error that would be returned would be the same: not
+// enough bytes. This library attempts to do no validation, it will only return
+// false if there are not enough bytes for an item to be read. For example, the
+// ReadDocument function checks the length, if that length is larger than the
+// number of bytes availble, it will return false, if there are enough bytes, it
+// will return those bytes and true. It is the consumers responsibility to
+// validate those bytes.
+//
+// The Append* functions within this package will append the type value to the
+// given dst slice. If the slice has enough capacity, it will not grow the
+// slice. The Append*Element functions within this package operate in the same
+// way, but additionally append the BSON type and the key before the value.
+package bsoncore
+
+import (
+	"bytes"
+	"fmt"
+	"math"
+	"time"
+
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+	"github.com/mongodb/mongo-go-driver/bson/primitive"
+)
+
+// AppendType will append t to dst and return the extended buffer.
+func AppendType(dst []byte, t bsontype.Type) []byte { return append(dst, byte(t)) }
+
+// AppendKey will append key to dst and return the extended buffer.
+func AppendKey(dst []byte, key string) []byte { return append(dst, key+string(0x00)...) }
+
+// AppendHeader will append Type t and key to dst and return the extended
+// buffer.
+func AppendHeader(dst []byte, t bsontype.Type, key string) []byte {
+	dst = AppendType(dst, t)
+	dst = append(dst, key...)
+	return append(dst, 0x00)
+	// return append(AppendType(dst, t), key+string(0x00)...)
+}
+
+// TODO(skriptble): All of the Read* functions should return src resliced to start just after what
+// was read.
+
+// ReadType will return the first byte of the provided []byte as a type. If
+// there is no availble byte, false is returned.
+func ReadType(src []byte) (bsontype.Type, []byte, bool) {
+	if len(src) < 1 {
+		return 0, src, false
+	}
+	return bsontype.Type(src[0]), src[1:], true
+}
+
+// ReadKey will read a key from src. The 0x00 byte will not be present
+// in the returned string. If there are not enough bytes available, false is
+// returned.
+func ReadKey(src []byte) (string, []byte, bool) { return readcstring(src) }
+
+// ReadKeyBytes will read a key from src as bytes. The 0x00 byte will
+// not be present in the returned string. If there are not enough bytes
+// available, false is returned.
+func ReadKeyBytes(src []byte) ([]byte, []byte, bool) { return readcstringbytes(src) }
+
+// ReadHeader will read a type byte and a key from src. If both of these
+// values cannot be read, false is returned.
+func ReadHeader(src []byte) (t bsontype.Type, key string, rem []byte, ok bool) {
+	t, rem, ok = ReadType(src)
+	if !ok {
+		return 0, "", src, false
+	}
+	key, rem, ok = ReadKey(rem)
+	if !ok {
+		return 0, "", src, false
+	}
+
+	return t, key, rem, true
+}
+
+// ReadHeaderBytes will read a type and a key from src and the remainder of the bytes
+// are returned as rem. If either the type or key cannot be red, ok will be false.
+func ReadHeaderBytes(src []byte) (header []byte, rem []byte, ok bool) {
+	if len(src) < 1 {
+		return nil, src, false
+	}
+	idx := bytes.IndexByte(src[1:], 0x00)
+	if idx == -1 {
+		return nil, src, false
+	}
+	return src[:idx], src[idx+1:], true
+}
+
+// ReadElement reads the next full element from src. It returns the element, the remaining bytes in
+// the slice, and a boolean indicating if the read was successful.
+func ReadElement(src []byte) (Element, []byte, bool) {
+	if len(src) < 1 {
+		return nil, src, false
+	}
+	t := bsontype.Type(src[0])
+	idx := bytes.IndexByte(src[1:], 0x00)
+	if idx == -1 {
+		return nil, src, false
+	}
+	length, ok := valueLength(src[idx+2:], t) // We add 2 here because we called IndexByte with src[1:]
+	if !ok {
+		return nil, src, false
+	}
+	elemLength := 1 + idx + 1 + int(length)
+	if elemLength > len(src) {
+		return nil, src, false
+	}
+	return src[:elemLength], src[elemLength:], true
+}
+
+// ReadValue reads the next value as the provided types and returns a Value, the remaining bytes,
+// and a boolean indicating if the read was successful.
+func ReadValue(src []byte, t bsontype.Type) (Value, []byte, bool) {
+	data, rem, ok := readValue(src, t)
+	if !ok {
+		return Value{}, src, false
+	}
+	return Value{Type: t, Data: data}, rem, true
+}
+
+// AppendDouble will append f to dst and return the extended buffer.
+func AppendDouble(dst []byte, f float64) []byte {
+	return appendu64(dst, math.Float64bits(f))
+}
+
+// AppendDoubleElement will append a BSON double element using key and f to dst
+// and return the extended buffer.
+func AppendDoubleElement(dst []byte, key string, f float64) []byte {
+	return AppendDouble(AppendHeader(dst, bsontype.Double, key), f)
+}
+
+// ReadDouble will read a float64 from src. If there are not enough bytes it
+// will return false.
+func ReadDouble(src []byte) (float64, []byte, bool) {
+	bits, src, ok := readu64(src)
+	if !ok {
+		return 0, src, false
+	}
+	return math.Float64frombits(bits), src, true
+}
+
+// AppendString will append s to dst and return the extended buffer.
+func AppendString(dst []byte, s string) []byte {
+	return appendstring(dst, s)
+}
+
+// AppendStringElement will append a BSON string element using key and val to dst
+// and return the extended buffer.
+func AppendStringElement(dst []byte, key, val string) []byte {
+	return AppendString(AppendHeader(dst, bsontype.String, key), val)
+}
+
+// ReadString will read a string from src. If there are not enough bytes it
+// will return false.
+func ReadString(src []byte) (string, []byte, bool) {
+	return readstring(src)
+}
+
+// AppendDocumentStart reserves a document's length and returns the index where the length begins.
+// This index can later be used to write the length of the document.
+//
+// TODO(skriptble): We really need AppendDocumentStart and AppendDocumentEnd.
+// AppendDocumentStart would handle calling ReserveLength and providing the index of the start of
+// the document. AppendDocumentEnd would handle taking that start index, adding the null byte,
+// calculating the length, and filling in the length at the start of the document.
+func AppendDocumentStart(dst []byte) (index int32, b []byte) { return ReserveLength(dst) }
+
+// AppendDocumentStartInline functions the same as AppendDocumentStart but takes a pointer to the
+// index int32 which allows this function to be used inline.
+func AppendDocumentStartInline(dst []byte, index *int32) []byte {
+	idx, doc := AppendDocumentStart(dst)
+	*index = idx
+	return doc
+}
+
+// AppendDocumentElementStart writes a document element header and then reserves the length bytes.
+func AppendDocumentElementStart(dst []byte, key string) (index int32, b []byte) {
+	return AppendDocumentStart(AppendHeader(dst, bsontype.EmbeddedDocument, key))
+}
+
+// AppendDocumentEnd writes the null byte for a document and updates the length of the document.
+// The index should be the beginning of the document's length bytes.
+func AppendDocumentEnd(dst []byte, index int32) ([]byte, error) {
+	if int(index) > len(dst)-4 {
+		return dst, fmt.Errorf("not enough bytes available after index to write length")
+	}
+	dst = append(dst, 0x00)
+	dst = UpdateLength(dst, index, int32(len(dst[index:])))
+	return dst, nil
+}
+
+// AppendDocument will append doc to dst and return the extended buffer.
+func AppendDocument(dst []byte, doc []byte) []byte { return append(dst, doc...) }
+
+// AppendDocumentElement will append a BSON embeded document element using key
+// and doc to dst and return the extended buffer.
+func AppendDocumentElement(dst []byte, key string, doc []byte) []byte {
+	return AppendDocument(AppendHeader(dst, bsontype.EmbeddedDocument, key), doc)
+}
+
+// BuildDocument will create a document with the given elements and will append it to dst.
+func BuildDocument(dst []byte, elems []byte) []byte {
+	idx, dst := ReserveLength(dst)
+	dst = append(dst, elems...)
+	dst = append(dst, 0x00)
+	dst = UpdateLength(dst, idx, int32(len(dst[idx:])))
+	return dst
+}
+
+// ReadDocument will read a document from src. If there are not enough bytes it
+// will return false.
+func ReadDocument(src []byte) (doc Document, rem []byte, ok bool) { return readLengthBytes(src) }
+
+// AppendArrayStart appends the length bytes to an array and then returns the index of the start
+// of those length bytes.
+func AppendArrayStart(dst []byte) (index int32, b []byte) { return ReserveLength(dst) }
+
+// AppendArrayElementStart appends an array element header and then the length bytes for an array,
+// returning the index where the length starts.
+func AppendArrayElementStart(dst []byte, key string) (index int32, b []byte) {
+	return AppendArrayStart(AppendHeader(dst, bsontype.Array, key))
+}
+
+// AppendArrayEnd appends the null byte to an array and calculates the length, inserting that
+// calculated length starting at index.
+func AppendArrayEnd(dst []byte, index int32) ([]byte, error) { return AppendDocumentEnd(dst, index) }
+
+// AppendArray will append arr to dst and return the extended buffer.
+func AppendArray(dst []byte, arr []byte) []byte { return append(dst, arr...) }
+
+// AppendArrayElement will append a BSON array element using key and arr to dst
+// and return the extended buffer.
+func AppendArrayElement(dst []byte, key string, arr []byte) []byte {
+	return AppendArray(AppendHeader(dst, bsontype.Array, key), arr)
+}
+
+// ReadArray will read an array from src. If there are not enough bytes it
+// will return false.
+func ReadArray(src []byte) (arr Document, rem []byte, ok bool) { return readLengthBytes(src) }
+
+// AppendBinary will append subtype and b to dst and return the extended buffer.
+func AppendBinary(dst []byte, subtype byte, b []byte) []byte {
+	if subtype == 0x02 {
+		return appendBinarySubtype2(dst, subtype, b)
+	}
+	dst = append(appendLength(dst, int32(len(b))), subtype)
+	return append(dst, b...)
+}
+
+// AppendBinaryElement will append a BSON binary element using key, subtype, and
+// b to dst and return the extended buffer.
+func AppendBinaryElement(dst []byte, key string, subtype byte, b []byte) []byte {
+	return AppendBinary(AppendHeader(dst, bsontype.Binary, key), subtype, b)
+}
+
+// ReadBinary will read a subtype and bin from src. If there are not enough bytes it
+// will return false.
+func ReadBinary(src []byte) (subtype byte, bin []byte, rem []byte, ok bool) {
+	length, rem, ok := ReadLength(src)
+	if !ok {
+		return 0x00, nil, src, false
+	}
+	if len(rem) < 1 { // subtype
+		return 0x00, nil, src, false
+	}
+	subtype, rem = rem[0], rem[1:]
+
+	if len(rem) < int(length) {
+		return 0x00, nil, src, false
+	}
+
+	if subtype == 0x02 {
+		length, rem, ok = ReadLength(rem)
+		if !ok || len(rem) < int(length) {
+			return 0x00, nil, src, false
+		}
+	}
+
+	return subtype, rem[:length], rem[length:], true
+}
+
+// AppendUndefinedElement will append a BSON undefined element using key to dst
+// and return the extended buffer.
+func AppendUndefinedElement(dst []byte, key string) []byte {
+	return AppendHeader(dst, bsontype.Undefined, key)
+}
+
+// AppendObjectID will append oid to dst and return the extended buffer.
+func AppendObjectID(dst []byte, oid primitive.ObjectID) []byte { return append(dst, oid[:]...) }
+
+// AppendObjectIDElement will append a BSON ObjectID element using key and oid to dst
+// and return the extended buffer.
+func AppendObjectIDElement(dst []byte, key string, oid primitive.ObjectID) []byte {
+	return AppendObjectID(AppendHeader(dst, bsontype.ObjectID, key), oid)
+}
+
+// ReadObjectID will read an ObjectID from src. If there are not enough bytes it
+// will return false.
+func ReadObjectID(src []byte) (primitive.ObjectID, []byte, bool) {
+	if len(src) < 12 {
+		return primitive.ObjectID{}, src, false
+	}
+	var oid primitive.ObjectID
+	copy(oid[:], src[0:12])
+	return oid, src[12:], true
+}
+
+// AppendBoolean will append b to dst and return the extended buffer.
+func AppendBoolean(dst []byte, b bool) []byte {
+	if b {
+		return append(dst, 0x01)
+	}
+	return append(dst, 0x00)
+}
+
+// AppendBooleanElement will append a BSON boolean element using key and b to dst
+// and return the extended buffer.
+func AppendBooleanElement(dst []byte, key string, b bool) []byte {
+	return AppendBoolean(AppendHeader(dst, bsontype.Boolean, key), b)
+}
+
+// ReadBoolean will read a bool from src. If there are not enough bytes it
+// will return false.
+func ReadBoolean(src []byte) (bool, []byte, bool) {
+	if len(src) < 1 {
+		return false, src, false
+	}
+
+	return src[0] == 0x01, src[1:], true
+}
+
+// AppendDateTime will append dt to dst and return the extended buffer.
+func AppendDateTime(dst []byte, dt int64) []byte { return appendi64(dst, dt) }
+
+// AppendDateTimeElement will append a BSON datetime element using key and dt to dst
+// and return the extended buffer.
+func AppendDateTimeElement(dst []byte, key string, dt int64) []byte {
+	return AppendDateTime(AppendHeader(dst, bsontype.DateTime, key), dt)
+}
+
+// ReadDateTime will read an int64 datetime from src. If there are not enough bytes it
+// will return false.
+func ReadDateTime(src []byte) (int64, []byte, bool) { return readi64(src) }
+
+// AppendTime will append time as a BSON DateTime to dst and return the extended buffer.
+func AppendTime(dst []byte, t time.Time) []byte {
+	return AppendDateTime(dst, t.Unix()*1000+int64(t.Nanosecond()/1e6))
+}
+
+// AppendTimeElement will append a BSON datetime element using key and dt to dst
+// and return the extended buffer.
+func AppendTimeElement(dst []byte, key string, t time.Time) []byte {
+	return AppendTime(AppendHeader(dst, bsontype.DateTime, key), t)
+}
+
+// ReadTime will read an time.Time datetime from src. If there are not enough bytes it
+// will return false.
+func ReadTime(src []byte) (time.Time, []byte, bool) {
+	dt, rem, ok := readi64(src)
+	return time.Unix(dt/1e3, dt%1e3*1e6), rem, ok
+}
+
+// AppendNullElement will append a BSON null element using key to dst
+// and return the extended buffer.
+func AppendNullElement(dst []byte, key string) []byte { return AppendHeader(dst, bsontype.Null, key) }
+
+// AppendRegex will append pattern and options to dst and return the extended buffer.
+func AppendRegex(dst []byte, pattern, options string) []byte {
+	return append(dst, pattern+string(0x00)+options+string(0x00)...)
+}
+
+// AppendRegexElement will append a BSON regex element using key, pattern, and
+// options to dst and return the extended buffer.
+func AppendRegexElement(dst []byte, key, pattern, options string) []byte {
+	return AppendRegex(AppendHeader(dst, bsontype.Regex, key), pattern, options)
+}
+
+// ReadRegex will read a pattern and options from src. If there are not enough bytes it
+// will return false.
+func ReadRegex(src []byte) (pattern, options string, rem []byte, ok bool) {
+	pattern, rem, ok = readcstring(src)
+	if !ok {
+		return "", "", src, false
+	}
+	options, rem, ok = readcstring(rem)
+	if !ok {
+		return "", "", src, false
+	}
+	return pattern, options, rem, true
+}
+
+// AppendDBPointer will append ns and oid to dst and return the extended buffer.
+func AppendDBPointer(dst []byte, ns string, oid primitive.ObjectID) []byte {
+	return append(appendstring(dst, ns), oid[:]...)
+}
+
+// AppendDBPointerElement will append a BSON DBPointer element using key, ns,
+// and oid to dst and return the extended buffer.
+func AppendDBPointerElement(dst []byte, key, ns string, oid primitive.ObjectID) []byte {
+	return AppendDBPointer(AppendHeader(dst, bsontype.DBPointer, key), ns, oid)
+}
+
+// ReadDBPointer will read a ns and oid from src. If there are not enough bytes it
+// will return false.
+func ReadDBPointer(src []byte) (ns string, oid primitive.ObjectID, rem []byte, ok bool) {
+	ns, rem, ok = readstring(src)
+	if !ok {
+		return "", primitive.ObjectID{}, src, false
+	}
+	oid, rem, ok = ReadObjectID(rem)
+	if !ok {
+		return "", primitive.ObjectID{}, src, false
+	}
+	return ns, oid, rem, true
+}
+
+// AppendJavaScript will append js to dst and return the extended buffer.
+func AppendJavaScript(dst []byte, js string) []byte { return appendstring(dst, js) }
+
+// AppendJavaScriptElement will append a BSON JavaScript element using key and
+// js to dst and return the extended buffer.
+func AppendJavaScriptElement(dst []byte, key, js string) []byte {
+	return AppendJavaScript(AppendHeader(dst, bsontype.JavaScript, key), js)
+}
+
+// ReadJavaScript will read a js string from src. If there are not enough bytes it
+// will return false.
+func ReadJavaScript(src []byte) (js string, rem []byte, ok bool) { return readstring(src) }
+
+// AppendSymbol will append symbol to dst and return the extended buffer.
+func AppendSymbol(dst []byte, symbol string) []byte { return appendstring(dst, symbol) }
+
+// AppendSymbolElement will append a BSON symbol element using key and symbol to dst
+// and return the extended buffer.
+func AppendSymbolElement(dst []byte, key, symbol string) []byte {
+	return AppendSymbol(AppendHeader(dst, bsontype.Symbol, key), symbol)
+}
+
+// ReadSymbol will read a symbol string from src. If there are not enough bytes it
+// will return false.
+func ReadSymbol(src []byte) (symbol string, rem []byte, ok bool) { return readstring(src) }
+
+// AppendCodeWithScope will append code and scope to dst and return the extended buffer.
+func AppendCodeWithScope(dst []byte, code string, scope []byte) []byte {
+	length := int32(4 + 4 + len(code) + 1 + len(scope)) // length of cws, length of code, code, 0x00, scope
+	dst = appendLength(dst, length)
+
+	return append(appendstring(dst, code), scope...)
+}
+
+// AppendCodeWithScopeElement will append a BSON code with scope element using
+// key, code, and scope to dst
+// and return the extended buffer.
+func AppendCodeWithScopeElement(dst []byte, key, code string, scope []byte) []byte {
+	return AppendCodeWithScope(AppendHeader(dst, bsontype.CodeWithScope, key), code, scope)
+}
+
+// ReadCodeWithScope will read code and scope from src. If there are not enough bytes it
+// will return false.
+func ReadCodeWithScope(src []byte) (code string, scope []byte, rem []byte, ok bool) {
+	length, rem, ok := ReadLength(src)
+	if !ok || len(src) < int(length) {
+		return "", nil, src, false
+	}
+
+	code, rem, ok = readstring(rem)
+	if !ok {
+		return "", nil, src, false
+	}
+
+	scope, rem, ok = ReadDocument(rem)
+	if !ok {
+		return "", nil, src, false
+	}
+	return code, scope, rem, true
+}
+
+// AppendInt32 will append i32 to dst and return the extended buffer.
+func AppendInt32(dst []byte, i32 int32) []byte { return appendi32(dst, i32) }
+
+// AppendInt32Element will append a BSON int32 element using key and i32 to dst
+// and return the extended buffer.
+func AppendInt32Element(dst []byte, key string, i32 int32) []byte {
+	return AppendInt32(AppendHeader(dst, bsontype.Int32, key), i32)
+}
+
+// ReadInt32 will read an int32 from src. If there are not enough bytes it
+// will return false.
+func ReadInt32(src []byte) (int32, []byte, bool) { return readi32(src) }
+
+// AppendTimestamp will append t and i to dst and return the extended buffer.
+func AppendTimestamp(dst []byte, t, i uint32) []byte {
+	return appendu32(appendu32(dst, i), t) // i is the lower 4 bytes, t is the higher 4 bytes
+}
+
+// AppendTimestampElement will append a BSON timestamp element using key, t, and
+// i to dst and return the extended buffer.
+func AppendTimestampElement(dst []byte, key string, t, i uint32) []byte {
+	return AppendTimestamp(AppendHeader(dst, bsontype.Timestamp, key), t, i)
+}
+
+// ReadTimestamp will read t and i from src. If there are not enough bytes it
+// will return false.
+func ReadTimestamp(src []byte) (t, i uint32, rem []byte, ok bool) {
+	i, rem, ok = readu32(src)
+	if !ok {
+		return 0, 0, src, false
+	}
+	t, rem, ok = readu32(rem)
+	if !ok {
+		return 0, 0, src, false
+	}
+	return t, i, rem, true
+}
+
+// AppendInt64 will append i64 to dst and return the extended buffer.
+func AppendInt64(dst []byte, i64 int64) []byte { return appendi64(dst, i64) }
+
+// AppendInt64Element will append a BSON int64 element using key and i64 to dst
+// and return the extended buffer.
+func AppendInt64Element(dst []byte, key string, i64 int64) []byte {
+	return AppendInt64(AppendHeader(dst, bsontype.Int64, key), i64)
+}
+
+// ReadInt64 will read an int64 from src. If there are not enough bytes it
+// will return false.
+func ReadInt64(src []byte) (int64, []byte, bool) { return readi64(src) }
+
+// AppendDecimal128 will append d128 to dst and return the extended buffer.
+func AppendDecimal128(dst []byte, d128 primitive.Decimal128) []byte {
+	high, low := d128.GetBytes()
+	return appendu64(appendu64(dst, low), high)
+}
+
+// AppendDecimal128Element will append a BSON primitive.28 element using key and
+// d128 to dst and return the extended buffer.
+func AppendDecimal128Element(dst []byte, key string, d128 primitive.Decimal128) []byte {
+	return AppendDecimal128(AppendHeader(dst, bsontype.Decimal128, key), d128)
+}
+
+// ReadDecimal128 will read a primitive.Decimal128 from src. If there are not enough bytes it
+// will return false.
+func ReadDecimal128(src []byte) (primitive.Decimal128, []byte, bool) {
+	l, rem, ok := readu64(src)
+	if !ok {
+		return primitive.Decimal128{}, src, false
+	}
+
+	h, rem, ok := readu64(rem)
+	if !ok {
+		return primitive.Decimal128{}, src, false
+	}
+
+	return primitive.NewDecimal128(h, l), rem, true
+}
+
+// AppendMaxKeyElement will append a BSON max key element using key to dst
+// and return the extended buffer.
+func AppendMaxKeyElement(dst []byte, key string) []byte {
+	return AppendHeader(dst, bsontype.MaxKey, key)
+}
+
+// AppendMinKeyElement will append a BSON min key element using key to dst
+// and return the extended buffer.
+func AppendMinKeyElement(dst []byte, key string) []byte {
+	return AppendHeader(dst, bsontype.MinKey, key)
+}
+
+// EqualValue will return true if the two values are equal.
+func EqualValue(t1, t2 bsontype.Type, v1, v2 []byte) bool {
+	if t1 != t2 {
+		return false
+	}
+	v1, _, ok := readValue(v1, t1)
+	if !ok {
+		return false
+	}
+	v2, _, ok = readValue(v2, t2)
+	if !ok {
+		return false
+	}
+	return bytes.Equal(v1, v2)
+}
+
+// valueLength will determine the length of the next value contained in src as if it
+// is type t. The returned bool will be false if there are not enough bytes in src for
+// a value of type t.
+func valueLength(src []byte, t bsontype.Type) (int32, bool) {
+	var length int32
+	ok := true
+	switch t {
+	case bsontype.Array, bsontype.EmbeddedDocument, bsontype.CodeWithScope:
+		length, _, ok = ReadLength(src)
+	case bsontype.Binary:
+		length, _, ok = ReadLength(src)
+		length += 4 + 1 // binary length + subtype byte
+	case bsontype.Boolean:
+		length = 1
+	case bsontype.DBPointer:
+		length, _, ok = ReadLength(src)
+		length += 4 + 12 // string length + ObjectID length
+	case bsontype.DateTime, bsontype.Double, bsontype.Int64, bsontype.Timestamp:
+		length = 8
+	case bsontype.Decimal128:
+		length = 16
+	case bsontype.Int32:
+		length = 4
+	case bsontype.JavaScript, bsontype.String, bsontype.Symbol:
+		length, _, ok = ReadLength(src)
+		length += 4
+	case bsontype.MaxKey, bsontype.MinKey, bsontype.Null, bsontype.Undefined:
+		length = 0
+	case bsontype.ObjectID:
+		length = 12
+	case bsontype.Regex:
+		regex := bytes.IndexByte(src, 0x00)
+		if regex < 0 {
+			ok = false
+			break
+		}
+		pattern := bytes.IndexByte(src[regex+1:], 0x00)
+		if pattern < 0 {
+			ok = false
+			break
+		}
+		length = int32(int64(regex) + 1 + int64(pattern) + 1)
+	default:
+		ok = false
+	}
+
+	return length, ok
+}
+
+func readValue(src []byte, t bsontype.Type) ([]byte, []byte, bool) {
+	length, ok := valueLength(src, t)
+	if !ok || int(length) > len(src) {
+		return nil, src, false
+	}
+
+	return src[:length], src[length:], true
+}
+
+// ReserveLength reserves the space required for length and returns the index where to write the length
+// and the []byte with reserved space.
+func ReserveLength(dst []byte) (int32, []byte) {
+	index := len(dst)
+	return int32(index), append(dst, 0x00, 0x00, 0x00, 0x00)
+}
+
+// UpdateLength updates the length at index with length and returns the []byte.
+func UpdateLength(dst []byte, index, length int32) []byte {
+	dst[index] = byte(length)
+	dst[index+1] = byte(length >> 8)
+	dst[index+2] = byte(length >> 16)
+	dst[index+3] = byte(length >> 24)
+	return dst
+}
+
+func appendLength(dst []byte, l int32) []byte { return appendi32(dst, l) }
+
+func appendi32(dst []byte, i32 int32) []byte {
+	return append(dst, byte(i32), byte(i32>>8), byte(i32>>16), byte(i32>>24))
+}
+
+// ReadLength reads an int32 length from src and returns the length and the remaining bytes. If
+// there aren't enough bytes to read a valid length, src is returned unomdified and the returned
+// bool will be false.
+func ReadLength(src []byte) (int32, []byte, bool) { return readi32(src) }
+
+func readi32(src []byte) (int32, []byte, bool) {
+	if len(src) < 4 {
+		return 0, src, false
+	}
+
+	return (int32(src[0]) | int32(src[1])<<8 | int32(src[2])<<16 | int32(src[3])<<24), src[4:], true
+}
+
+func appendi64(dst []byte, i64 int64) []byte {
+	return append(dst,
+		byte(i64), byte(i64>>8), byte(i64>>16), byte(i64>>24),
+		byte(i64>>32), byte(i64>>40), byte(i64>>48), byte(i64>>56),
+	)
+}
+
+func readi64(src []byte) (int64, []byte, bool) {
+	if len(src) < 8 {
+		return 0, src, false
+	}
+	i64 := (int64(src[0]) | int64(src[1])<<8 | int64(src[2])<<16 | int64(src[3])<<24 |
+		int64(src[4])<<32 | int64(src[5])<<40 | int64(src[6])<<48 | int64(src[7])<<56)
+	return i64, src[8:], true
+}
+
+func appendu32(dst []byte, u32 uint32) []byte {
+	return append(dst, byte(u32), byte(u32>>8), byte(u32>>16), byte(u32>>24))
+}
+
+func readu32(src []byte) (uint32, []byte, bool) {
+	if len(src) < 4 {
+		return 0, src, false
+	}
+
+	return (uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24), src[4:], true
+}
+
+func appendu64(dst []byte, u64 uint64) []byte {
+	return append(dst,
+		byte(u64), byte(u64>>8), byte(u64>>16), byte(u64>>24),
+		byte(u64>>32), byte(u64>>40), byte(u64>>48), byte(u64>>56),
+	)
+}
+
+func readu64(src []byte) (uint64, []byte, bool) {
+	if len(src) < 8 {
+		return 0, src, false
+	}
+	u64 := (uint64(src[0]) | uint64(src[1])<<8 | uint64(src[2])<<16 | uint64(src[3])<<24 |
+		uint64(src[4])<<32 | uint64(src[5])<<40 | uint64(src[6])<<48 | uint64(src[7])<<56)
+	return u64, src[8:], true
+}
+
+// keep in sync with readcstringbytes
+func readcstring(src []byte) (string, []byte, bool) {
+	idx := bytes.IndexByte(src, 0x00)
+	if idx < 0 {
+		return "", src, false
+	}
+	return string(src[:idx]), src[idx+1:], true
+}
+
+// keep in sync with readcstring
+func readcstringbytes(src []byte) ([]byte, []byte, bool) {
+	idx := bytes.IndexByte(src, 0x00)
+	if idx < 0 {
+		return nil, src, false
+	}
+	return src[:idx], src[idx+1:], true
+}
+
+func appendstring(dst []byte, s string) []byte {
+	l := int32(len(s) + 1)
+	dst = appendLength(dst, l)
+	dst = append(dst, s...)
+	return append(dst, 0x00)
+}
+
+func readstring(src []byte) (string, []byte, bool) {
+	l, rem, ok := ReadLength(src)
+	if !ok {
+		return "", src, false
+	}
+	if len(src[4:]) < int(l) {
+		return "", src, false
+	}
+
+	return string(rem[:l-1]), rem[l:], true
+}
+
+// readLengthBytes attempts to read a length and that number of bytes. This
+// function requires that the length include the four bytes for itself.
+func readLengthBytes(src []byte) ([]byte, []byte, bool) {
+	l, _, ok := ReadLength(src)
+	if !ok {
+		return nil, src, false
+	}
+	if len(src) < int(l) {
+		return nil, src, false
+	}
+	return src[:l], src[l:], true
+}
+
+func appendBinarySubtype2(dst []byte, subtype byte, b []byte) []byte {
+	dst = appendLength(dst, int32(len(b)+4)) // The bytes we'll encode need to be 4 larger for the length bytes
+	dst = append(dst, subtype)
+	dst = appendLength(dst, int32(len(b)))
+	return append(dst, b...)
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/document.go b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/document.go
new file mode 100644
index 0000000..e655a51
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/document.go
@@ -0,0 +1,396 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package bsoncore
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+
+	"github.com/go-stack/stack"
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+)
+
+// DocumentValidationError is an error type returned when attempting to validate a document.
+type DocumentValidationError string
+
+func (dve DocumentValidationError) Error() string { return string(dve) }
+
+// NewDocumentLengthError creates and returns an error for when the length of a document exceeds the
+// bytes available.
+func NewDocumentLengthError(length, rem int) error {
+	return DocumentValidationError(
+		fmt.Sprintf("document length exceeds available bytes. length=%d remainingBytes=%d", length, rem),
+	)
+}
+
+// InsufficientBytesError indicates that there were not enough bytes to read the next component.
+type InsufficientBytesError struct {
+	Source    []byte
+	Remaining []byte
+	Stack     stack.CallStack
+}
+
+// NewInsufficientBytesError creates a new InsufficientBytesError with the given Document, remaining
+// bytes, and the current stack.
+func NewInsufficientBytesError(src, rem []byte) InsufficientBytesError {
+	return InsufficientBytesError{Source: src, Remaining: rem, Stack: stack.Trace().TrimRuntime()}
+}
+
+// Error implements the error interface.
+func (ibe InsufficientBytesError) Error() string {
+	return "too few bytes to read next component"
+}
+
+// ErrorStack returns a string representing the stack at the point where the error occurred.
+func (ibe InsufficientBytesError) ErrorStack() string {
+	s := bytes.NewBufferString("too few bytes to read next component: [")
+
+	for i, call := range ibe.Stack {
+		if i != 0 {
+			s.WriteString(", ")
+		}
+
+		// go vet doesn't like %k even though it's part of stack's API, so we move the format
+		// string so it doesn't complain. (We also can't make it a constant, or go vet still
+		// complains.)
+		callFormat := "%k.%n %v"
+
+		s.WriteString(fmt.Sprintf(callFormat, call, call, call))
+	}
+
+	s.WriteRune(']')
+
+	return s.String()
+}
+
+// Equal checks that err2 also is an ErrTooSmall.
+func (ibe InsufficientBytesError) Equal(err2 error) bool {
+	switch err2.(type) {
+	case InsufficientBytesError:
+		return true
+	default:
+		return false
+	}
+}
+
+// InvalidDepthTraversalError is returned when attempting a recursive Lookup when one component of
+// the path is neither an embedded document nor an array.
+type InvalidDepthTraversalError struct {
+	Key  string
+	Type bsontype.Type
+}
+
+func (idte InvalidDepthTraversalError) Error() string {
+	return fmt.Sprintf(
+		"attempt to traverse into %s, but it's type is %s, not %s nor %s",
+		idte.Key, idte.Type, bsontype.EmbeddedDocument, bsontype.Array,
+	)
+}
+
+// ErrMissingNull is returned when a document's last byte is not null.
+const ErrMissingNull DocumentValidationError = "document end is missing null byte"
+
+// ErrNilReader indicates that an operation was attempted on a nil io.Reader.
+var ErrNilReader = errors.New("nil reader")
+
+// ErrInvalidLength indicates that a length in a binary representation of a BSON document is invalid.
+var ErrInvalidLength = errors.New("document length is invalid")
+
+// ErrEmptyKey indicates that no key was provided to a Lookup method.
+var ErrEmptyKey = errors.New("empty key provided")
+
+// ErrElementNotFound indicates that an Element matching a certain condition does not exist.
+var ErrElementNotFound = errors.New("element not found")
+
+// ErrOutOfBounds indicates that an index provided to access something was invalid.
+var ErrOutOfBounds = errors.New("out of bounds")
+
+// Document is a raw bytes representation of a BSON document.
+type Document []byte
+
+// NewDocumentFromReader reads a document from r. This function will only validate the length is
+// correct and that the document ends with a null byte.
+func NewDocumentFromReader(r io.Reader) (Document, error) {
+	if r == nil {
+		return nil, ErrNilReader
+	}
+
+	var lengthBytes [4]byte
+
+	// ReadFull guarantees that we will have read at least len(lengthBytes) if err == nil
+	_, err := io.ReadFull(r, lengthBytes[:])
+	if err != nil {
+		return nil, err
+	}
+
+	length, _, _ := readi32(lengthBytes[:]) // ignore ok since we always have enough bytes to read a length
+	if length < 0 {
+		return nil, ErrInvalidLength
+	}
+	document := make([]byte, length)
+
+	copy(document, lengthBytes[:])
+
+	_, err = io.ReadFull(r, document[4:])
+	if err != nil {
+		return nil, err
+	}
+
+	if document[length-1] != 0x00 {
+		return nil, ErrMissingNull
+	}
+
+	return document, nil
+}
+
+// Lookup searches the document, potentially recursively, for the given key. If there are multiple
+// keys provided, this method will recurse down, as long as the top and intermediate nodes are
+// either documents or arrays. If an error occurs or if the value doesn't exist, an empty Value is
+// returned.
+func (d Document) Lookup(key ...string) Value {
+	val, _ := d.LookupErr(key...)
+	return val
+}
+
+// LookupErr is the same as Lookup, except it returns an error in addition to an empty Value.
+func (d Document) LookupErr(key ...string) (Value, error) {
+	if len(key) < 1 {
+		return Value{}, ErrEmptyKey
+	}
+	length, rem, ok := ReadLength(d)
+	if !ok {
+		return Value{}, NewInsufficientBytesError(d, rem)
+	}
+
+	length -= 4
+
+	var elem Element
+	for length > 1 {
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			return Value{}, NewInsufficientBytesError(d, rem)
+		}
+		if elem.Key() != key[0] {
+			continue
+		}
+		if len(key) > 1 {
+			tt := bsontype.Type(elem[0])
+			switch tt {
+			case bsontype.EmbeddedDocument:
+				val, err := elem.Value().Document().LookupErr(key[1:]...)
+				if err != nil {
+					return Value{}, err
+				}
+				return val, nil
+			case bsontype.Array:
+				val, err := elem.Value().Array().LookupErr(key[1:]...)
+				if err != nil {
+					return Value{}, err
+				}
+				return val, nil
+			default:
+				return Value{}, InvalidDepthTraversalError{Key: elem.Key(), Type: tt}
+			}
+		}
+		return elem.ValueErr()
+	}
+	return Value{}, ErrElementNotFound
+}
+
+// Index searches for and retrieves the element at the given index. This method will panic if
+// the document is invalid or if the index is out of bounds.
+func (d Document) Index(index uint) Element {
+	elem, err := d.IndexErr(index)
+	if err != nil {
+		panic(err)
+	}
+	return elem
+}
+
+// IndexErr searches for and retrieves the element at the given index.
+func (d Document) IndexErr(index uint) (Element, error) {
+	length, rem, ok := ReadLength(d)
+	if !ok {
+		return nil, NewInsufficientBytesError(d, rem)
+	}
+
+	length -= 4
+
+	var current uint
+	var elem Element
+	for length > 1 {
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			return nil, NewInsufficientBytesError(d, rem)
+		}
+		if current != index {
+			current++
+			continue
+		}
+		return elem, nil
+	}
+	return nil, ErrOutOfBounds
+}
+
+// DebugString outputs a human readable version of Document. It will attempt to stringify the
+// valid components of the document even if the entire document is not valid.
+func (d Document) DebugString() string {
+	if len(d) < 5 {
+		return "<malformed>"
+	}
+	var buf bytes.Buffer
+	buf.WriteString("Document")
+	length, rem, _ := ReadLength(d) // We know we have enough bytes to read the length
+	buf.WriteByte('(')
+	buf.WriteString(strconv.Itoa(int(length)))
+	length -= 4
+	buf.WriteString("){")
+	var elem Element
+	var ok bool
+	for length > 1 {
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			buf.WriteString(fmt.Sprintf("<malformed (%d)>", length))
+			break
+		}
+		fmt.Fprintf(&buf, "%s ", elem.DebugString())
+	}
+	buf.WriteByte('}')
+
+	return buf.String()
+}
+
+// String outputs an ExtendedJSON version of Document. If the document is not valid, this method
+// returns an empty string.
+func (d Document) String() string {
+	if len(d) < 5 {
+		return ""
+	}
+	var buf bytes.Buffer
+	buf.WriteByte('{')
+
+	length, rem, _ := ReadLength(d) // We know we have enough bytes to read the length
+
+	length -= 4
+
+	var elem Element
+	var ok bool
+	first := true
+	for length > 1 {
+		if !first {
+			buf.WriteByte(',')
+		}
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			return ""
+		}
+		fmt.Fprintf(&buf, "%s", elem.String())
+		first = false
+	}
+	buf.WriteByte('}')
+
+	return buf.String()
+}
+
+// Elements returns this document as a slice of elements. The returned slice will contain valid
+// elements. If the document is not valid, the elements up to the invalid point will be returned
+// along with an error.
+func (d Document) Elements() ([]Element, error) {
+	length, rem, ok := ReadLength(d)
+	if !ok {
+		return nil, NewInsufficientBytesError(d, rem)
+	}
+
+	length -= 4
+
+	var elem Element
+	var elems []Element
+	for length > 1 {
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			return elems, NewInsufficientBytesError(d, rem)
+		}
+		if err := elem.Validate(); err != nil {
+			return elems, err
+		}
+		elems = append(elems, elem)
+	}
+	return elems, nil
+}
+
+// Values returns this document as a slice of values. The returned slice will contain valid values.
+// If the document is not valid, the values up to the invalid point will be returned along with an
+// error.
+func (d Document) Values() ([]Value, error) {
+	length, rem, ok := ReadLength(d)
+	if !ok {
+		return nil, NewInsufficientBytesError(d, rem)
+	}
+
+	length -= 4
+
+	var elem Element
+	var vals []Value
+	for length > 1 {
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			return vals, NewInsufficientBytesError(d, rem)
+		}
+		if err := elem.Value().Validate(); err != nil {
+			return vals, err
+		}
+		vals = append(vals, elem.Value())
+	}
+	return vals, nil
+}
+
+// Validate validates the document and ensures the elements contained within are valid.
+func (d Document) Validate() error {
+	length, rem, ok := ReadLength(d)
+	if !ok {
+		return NewInsufficientBytesError(d, rem)
+	}
+	if int(length) > len(d) {
+		return d.lengtherror(int(length), len(d))
+	}
+	if d[length-1] != 0x00 {
+		return ErrMissingNull
+	}
+
+	length -= 4
+	var elem Element
+
+	for length > 1 {
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			return NewInsufficientBytesError(d, rem)
+		}
+		err := elem.Validate()
+		if err != nil {
+			return err
+		}
+	}
+
+	if len(rem) < 1 || rem[0] != 0x00 {
+		return ErrMissingNull
+	}
+	return nil
+}
+
+func (Document) lengtherror(length, rem int) error {
+	return DocumentValidationError(fmt.Sprintf("document length exceeds available bytes. length=%d remainingBytes=%d", length, rem))
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/element.go b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/element.go
new file mode 100644
index 0000000..ccf9075
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/element.go
@@ -0,0 +1,152 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package bsoncore
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+)
+
+// MalformedElementError represents a class of errors that RawElement methods return.
+type MalformedElementError string
+
+func (mee MalformedElementError) Error() string { return string(mee) }
+
+// ErrElementMissingKey is returned when a RawElement is missing a key.
+const ErrElementMissingKey MalformedElementError = "element is missing key"
+
+// ErrElementMissingType is returned when a RawElement is missing a type.
+const ErrElementMissingType MalformedElementError = "element is missing type"
+
+// Element is a raw bytes representation of a BSON element.
+type Element []byte
+
+// Key returns the key for this element. If the element is not valid, this method returns an empty
+// string. If knowing if the element is valid is important, use KeyErr.
+func (e Element) Key() string {
+	key, _ := e.KeyErr()
+	return key
+}
+
+// KeyBytes returns the key for this element as a []byte. If the element is not valid, this method
+// returns an empty string. If knowing if the element is valid is important, use KeyErr. This method
+// will not include the null byte at the end of the key in the slice of bytes.
+func (e Element) KeyBytes() []byte {
+	key, _ := e.KeyBytesErr()
+	return key
+}
+
+// KeyErr returns the key for this element, returning an error if the element is not valid.
+func (e Element) KeyErr() (string, error) {
+	key, err := e.KeyBytesErr()
+	return string(key), err
+}
+
+// KeyBytesErr returns the key for this element as a []byte, returning an error if the element is
+// not valid.
+func (e Element) KeyBytesErr() ([]byte, error) {
+	if len(e) <= 0 {
+		return nil, ErrElementMissingType
+	}
+	idx := bytes.IndexByte(e[1:], 0x00)
+	if idx == -1 {
+		return nil, ErrElementMissingKey
+	}
+	return e[1 : idx+1], nil
+}
+
+// Validate ensures the element is a valid BSON element.
+func (e Element) Validate() error {
+	if len(e) < 1 {
+		return ErrElementMissingType
+	}
+	idx := bytes.IndexByte(e[1:], 0x00)
+	if idx == -1 {
+		return ErrElementMissingKey
+	}
+	return Value{Type: bsontype.Type(e[0]), Data: e[idx+2:]}.Validate()
+}
+
+// CompareKey will compare this element's key to key. This method makes it easy to compare keys
+// without needing to allocate a string. The key may be null terminated. If a valid key cannot be
+// read this method will return false.
+func (e Element) CompareKey(key []byte) bool {
+	if len(e) < 2 {
+		return false
+	}
+	idx := bytes.IndexByte(e[1:], 0x00)
+	if idx == -1 {
+		return false
+	}
+	if index := bytes.IndexByte(key, 0x00); index > -1 {
+		key = key[:index]
+	}
+	return bytes.Equal(e[1:idx+1], key)
+}
+
+// Value returns the value of this element. If the element is not valid, this method returns an
+// empty Value. If knowing if the element is valid is important, use ValueErr.
+func (e Element) Value() Value {
+	val, _ := e.ValueErr()
+	return val
+}
+
+// ValueErr returns the value for this element, returning an error if the element is not valid.
+func (e Element) ValueErr() (Value, error) {
+	if len(e) <= 0 {
+		return Value{}, ErrElementMissingType
+	}
+	idx := bytes.IndexByte(e[1:], 0x00)
+	if idx == -1 {
+		return Value{}, ErrElementMissingKey
+	}
+
+	val, rem, exists := ReadValue(e[idx+2:], bsontype.Type(e[0]))
+	if !exists {
+		return Value{}, NewInsufficientBytesError(e, rem)
+	}
+	return val, nil
+}
+
+// String implements the fmt.String interface. The output will be in extended JSON format.
+func (e Element) String() string {
+	if len(e) <= 0 {
+		return ""
+	}
+	t := bsontype.Type(e[0])
+	idx := bytes.IndexByte(e[1:], 0x00)
+	if idx == -1 {
+		return ""
+	}
+	key, valBytes := []byte(e[1:idx+1]), []byte(e[idx+2:])
+	val, _, valid := ReadValue(valBytes, t)
+	if !valid {
+		return ""
+	}
+	return fmt.Sprintf(`"%s": %v`, key, val)
+}
+
+// DebugString outputs a human readable version of RawElement. It will attempt to stringify the
+// valid components of the element even if the entire element is not valid.
+func (e Element) DebugString() string {
+	if len(e) <= 0 {
+		return "<malformed>"
+	}
+	t := bsontype.Type(e[0])
+	idx := bytes.IndexByte(e[1:], 0x00)
+	if idx == -1 {
+		return fmt.Sprintf(`bson.Element{[%s]<malformed>}`, t)
+	}
+	key, valBytes := []byte(e[1:idx+1]), []byte(e[idx+2:])
+	val, _, valid := ReadValue(valBytes, t)
+	if !valid {
+		return fmt.Sprintf(`bson.Element{[%s]"%s": <malformed>}`, t, key)
+	}
+	return fmt.Sprintf(`bson.Element{[%s]"%s": %v}`, t, key, val)
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/tables.go b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/tables.go
new file mode 100644
index 0000000..9fd903f
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/tables.go
@@ -0,0 +1,223 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+//
+// Based on github.com/golang/go by The Go Authors
+// See THIRD-PARTY-NOTICES for original license terms.
+
+package bsoncore
+
+import "unicode/utf8"
+
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      true,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      true,
+	'=':      true,
+	'>':      true,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
+
+// htmlSafeSet holds the value true if the ASCII character with the given
+// array position can be safely represented inside a JSON string, embedded
+// inside of HTML <script> tags, without any additional escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), the backslash character ("\"), HTML opening and closing
+// tags ("<" and ">"), and the ampersand ("&").
+var htmlSafeSet = [utf8.RuneSelf]bool{
+	' ':      true,
+	'!':      true,
+	'"':      false,
+	'#':      true,
+	'$':      true,
+	'%':      true,
+	'&':      false,
+	'\'':     true,
+	'(':      true,
+	')':      true,
+	'*':      true,
+	'+':      true,
+	',':      true,
+	'-':      true,
+	'.':      true,
+	'/':      true,
+	'0':      true,
+	'1':      true,
+	'2':      true,
+	'3':      true,
+	'4':      true,
+	'5':      true,
+	'6':      true,
+	'7':      true,
+	'8':      true,
+	'9':      true,
+	':':      true,
+	';':      true,
+	'<':      false,
+	'=':      true,
+	'>':      false,
+	'?':      true,
+	'@':      true,
+	'A':      true,
+	'B':      true,
+	'C':      true,
+	'D':      true,
+	'E':      true,
+	'F':      true,
+	'G':      true,
+	'H':      true,
+	'I':      true,
+	'J':      true,
+	'K':      true,
+	'L':      true,
+	'M':      true,
+	'N':      true,
+	'O':      true,
+	'P':      true,
+	'Q':      true,
+	'R':      true,
+	'S':      true,
+	'T':      true,
+	'U':      true,
+	'V':      true,
+	'W':      true,
+	'X':      true,
+	'Y':      true,
+	'Z':      true,
+	'[':      true,
+	'\\':     false,
+	']':      true,
+	'^':      true,
+	'_':      true,
+	'`':      true,
+	'a':      true,
+	'b':      true,
+	'c':      true,
+	'd':      true,
+	'e':      true,
+	'f':      true,
+	'g':      true,
+	'h':      true,
+	'i':      true,
+	'j':      true,
+	'k':      true,
+	'l':      true,
+	'm':      true,
+	'n':      true,
+	'o':      true,
+	'p':      true,
+	'q':      true,
+	'r':      true,
+	's':      true,
+	't':      true,
+	'u':      true,
+	'v':      true,
+	'w':      true,
+	'x':      true,
+	'y':      true,
+	'z':      true,
+	'{':      true,
+	'|':      true,
+	'}':      true,
+	'~':      true,
+	'\u007f': true,
+}
diff --git a/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/value.go b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/value.go
new file mode 100644
index 0000000..f0593d2
--- /dev/null
+++ b/vendor/github.com/mongodb/mongo-go-driver/x/bsonx/bsoncore/value.go
@@ -0,0 +1,901 @@
+// Copyright (C) MongoDB, Inc. 2017-present.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+package bsoncore
+
+import (
+	"bytes"
+	"encoding/base64"
+	"fmt"
+	"math"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+	"unicode/utf8"
+
+	"github.com/mongodb/mongo-go-driver/bson/bsontype"
+	"github.com/mongodb/mongo-go-driver/bson/primitive"
+)
+
+// ElementTypeError specifies that a method to obtain a BSON value an incorrect type was called on a bson.Value.
+type ElementTypeError struct {
+	Method string
+	Type   bsontype.Type
+}
+
+// Error implements the error interface.
+func (ete ElementTypeError) Error() string {
+	return "Call of " + ete.Method + " on " + ete.Type.String() + " type"
+}
+
+// Value represents a BSON value with a type and raw bytes.
+type Value struct {
+	Type bsontype.Type
+	Data []byte
+}
+
+// Validate ensures the value is a valid BSON value.
+func (v Value) Validate() error {
+	_, _, valid := readValue(v.Data, v.Type)
+	if !valid {
+		return NewInsufficientBytesError(v.Data, v.Data)
+	}
+	return nil
+}
+
+// IsNumber returns true if the type of v is a numeric BSON type.
+func (v Value) IsNumber() bool {
+	switch v.Type {
+	case bsontype.Double, bsontype.Int32, bsontype.Int64, bsontype.Decimal128:
+		return true
+	default:
+		return false
+	}
+}
+
+// AsInt32 returns a BSON number as an int32. If the BSON type is not a numeric one, this method
+// will panic.
+//
+// TODO(skriptble): Add support for Decimal128.
+func (v Value) AsInt32() int32 { return 0 }
+
+// AsInt32OK functions the same as AsInt32 but returns a boolean instead of panicking. False
+// indicates an error.
+//
+// TODO(skriptble): Add support for Decimal128.
+func (v Value) AsInt32OK() (int32, bool) { return 0, false }
+
+// AsInt64 returns a BSON number as an int64. If the BSON type is not a numeric one, this method
+// will panic.
+//
+// TODO(skriptble): Add support for Decimal128.
+func (v Value) AsInt64() int64 { return 0 }
+
+// AsInt64OK functions the same as AsInt64 but returns a boolean instead of panicking. False
+// indicates an error.
+//
+// TODO(skriptble): Add support for Decimal128.
+func (v Value) AsInt64OK() (int64, bool) { return 0, false }
+
+// AsFloat64 returns a BSON number as an float64. If the BSON type is not a numeric one, this method
+// will panic.
+//
+// TODO(skriptble): Add support for Decimal128.
+func (v Value) AsFloat64() float64 { return 0 }
+
+// AsFloat64OK functions the same as AsFloat64 but returns a boolean instead of panicking. False
+// indicates an error.
+//
+// TODO(skriptble): Add support for Decimal128.
+func (v Value) AsFloat64OK() (float64, bool) { return 0, false }
+
+// Add will add this value to another. This is currently only implemented for strings and numbers.
+// If either value is a string, the other type is coerced into a string and added to the other.
+//
+// This method will alter v and will attempt to reuse the []byte of v. If the []byte is too small,
+// it will be expanded.
+func (v *Value) Add(v2 Value) error { return nil }
+
+// Equal compaes v to v2 and returns true if they are equal.
+func (v Value) Equal(v2 Value) bool {
+	if v.Type != v2.Type {
+		return false
+	}
+
+	return bytes.Equal(v.Data, v2.Data)
+}
+
+// String implements the fmt.String interface. This method will return values in extended JSON
+// format. If the value is not valid, this returns an empty string
+func (v Value) String() string {
+	switch v.Type {
+	case bsontype.Double:
+		f64, ok := v.DoubleOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$numberDouble":"%s"}`, formatDouble(f64))
+	case bsontype.String:
+		str, ok := v.StringValueOK()
+		if !ok {
+			return ""
+		}
+		return escapeString(str)
+	case bsontype.EmbeddedDocument:
+		doc, ok := v.DocumentOK()
+		if !ok {
+			return ""
+		}
+		return doc.String()
+	case bsontype.Array:
+		arr, ok := v.ArrayOK()
+		if !ok {
+			return ""
+		}
+		return docAsArray(arr, false)
+	case bsontype.Binary:
+		subtype, data, ok := v.BinaryOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$binary":{"base64":"%s","subType":"%02x"}}`, base64.StdEncoding.EncodeToString(data), subtype)
+	case bsontype.Undefined:
+		return `{"$undefined":true}`
+	case bsontype.ObjectID:
+		oid, ok := v.ObjectIDOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$oid":%s}`, oid.Hex())
+	case bsontype.Boolean:
+		b, ok := v.BooleanOK()
+		if !ok {
+			return ""
+		}
+		return strconv.FormatBool(b)
+	case bsontype.DateTime:
+		dt, ok := v.DateTimeOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$date":{"$numberLong":"%d"}}`, dt)
+	case bsontype.Null:
+		return "null"
+	case bsontype.Regex:
+		pattern, options, ok := v.RegexOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(
+			`{"$regularExpression":{"pattern":%s,"options":"%s"}}`,
+			escapeString(pattern), sortStringAlphebeticAscending(options),
+		)
+	case bsontype.DBPointer:
+		ns, pointer, ok := v.DBPointerOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$dbPointer":{"$ref":%s,"$id":{"$oid":"%s"}}}`, escapeString(ns), pointer.Hex())
+	case bsontype.JavaScript:
+		js, ok := v.JavaScriptOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$code":%s}`, escapeString(js))
+	case bsontype.Symbol:
+		symbol, ok := v.SymbolOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$symbol":%s}`, escapeString(symbol))
+	case bsontype.CodeWithScope:
+		code, scope, ok := v.CodeWithScopeOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope)
+	case bsontype.Int32:
+		i32, ok := v.Int32OK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$numberInt":"%d"}`, i32)
+	case bsontype.Timestamp:
+		t, i, ok := v.TimestampOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$timestamp":{"t":"%s","i":"%s"}}`, strconv.FormatUint(uint64(t), 10), strconv.FormatUint(uint64(i), 10))
+	case bsontype.Int64:
+		i64, ok := v.Int64OK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$numberLong":"%d"}`, i64)
+	case bsontype.Decimal128:
+		d128, ok := v.Decimal128OK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$numberDecimal":"%s"}`, d128.String())
+	case bsontype.MinKey:
+		return `{"$minKey":1}`
+	case bsontype.MaxKey:
+		return `{"$maxKey":1}`
+	default:
+		return ""
+	}
+}
+
+// DebugString outputs a human readable version of Document. It will attempt to stringify the
+// valid components of the document even if the entire document is not valid.
+func (v Value) DebugString() string {
+	switch v.Type {
+	case bsontype.String:
+		str, ok := v.StringValueOK()
+		if !ok {
+			return "<malformed>"
+		}
+		return escapeString(str)
+	case bsontype.EmbeddedDocument:
+		doc, ok := v.DocumentOK()
+		if !ok {
+			return "<malformed>"
+		}
+		return doc.DebugString()
+	case bsontype.Array:
+		arr, ok := v.ArrayOK()
+		if !ok {
+			return "<malformed>"
+		}
+		return docAsArray(arr, true)
+	case bsontype.CodeWithScope:
+		code, scope, ok := v.CodeWithScopeOK()
+		if !ok {
+			return ""
+		}
+		return fmt.Sprintf(`{"$code":%s,"$scope":%s}`, code, scope.DebugString())
+	default:
+		str := v.String()
+		if str == "" {
+			return "<malformed>"
+		}
+		return str
+	}
+}
+
+// Double returns the float64 value for this element.
+// It panics if e's BSON type is not bsontype.Double.
+func (v Value) Double() float64 {
+	if v.Type != bsontype.Double {
+		panic(ElementTypeError{"bsoncore.Value.Double", v.Type})
+	}
+	f64, _, ok := ReadDouble(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return f64
+}
+
+// DoubleOK is the same as Double, but returns a boolean instead of panicking.
+func (v Value) DoubleOK() (float64, bool) {
+	if v.Type != bsontype.Double {
+		return 0, false
+	}
+	f64, _, ok := ReadDouble(v.Data)
+	if !ok {
+		return 0, false
+	}
+	return f64, true
+}
+
+// StringValue returns the string balue for this element.
+// It panics if e's BSON type is not bsontype.String.
+//
+// NOTE: This method is called StringValue to avoid a collision with the String method which
+// implements the fmt.Stringer interface.
+func (v Value) StringValue() string {
+	if v.Type != bsontype.String {
+		panic(ElementTypeError{"bsoncore.Value.StringValue", v.Type})
+	}
+	str, _, ok := ReadString(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return str
+}
+
+// StringValueOK is the same as StringValue, but returns a boolean instead of
+// panicking.
+func (v Value) StringValueOK() (string, bool) {
+	if v.Type != bsontype.String {
+		return "", false
+	}
+	str, _, ok := ReadString(v.Data)
+	if !ok {
+		return "", false
+	}
+	return str, true
+}
+
+// Document returns the BSON document the Value represents as a Document. It panics if the
+// value is a BSON type other than document.
+func (v Value) Document() Document {
+	if v.Type != bsontype.EmbeddedDocument {
+		panic(ElementTypeError{"bsoncore.Value.Document", v.Type})
+	}
+	doc, _, ok := ReadDocument(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return doc
+}
+
+// DocumentOK is the same as Document, except it returns a boolean
+// instead of panicking.
+func (v Value) DocumentOK() (Document, bool) {
+	if v.Type != bsontype.EmbeddedDocument {
+		return nil, false
+	}
+	doc, _, ok := ReadDocument(v.Data)
+	if !ok {
+		return nil, false
+	}
+	return doc, true
+}
+
+// Array returns the BSON array the Value represents as an Array. It panics if the
+// value is a BSON type other than array.
+func (v Value) Array() Document {
+	if v.Type != bsontype.Array {
+		panic(ElementTypeError{"bsoncore.Value.Array", v.Type})
+	}
+	arr, _, ok := ReadArray(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return arr
+}
+
+// ArrayOK is the same as Array, except it returns a boolean instead
+// of panicking.
+func (v Value) ArrayOK() (Document, bool) {
+	if v.Type != bsontype.Array {
+		return nil, false
+	}
+	arr, _, ok := ReadArray(v.Data)
+	if !ok {
+		return nil, false
+	}
+	return arr, true
+}
+
+// Binary returns the BSON binary value the Value represents. It panics if the value is a BSON type
+// other than binary.
+func (v Value) Binary() (subtype byte, data []byte) {
+	if v.Type != bsontype.Binary {
+		panic(ElementTypeError{"bsoncore.Value.Binary", v.Type})
+	}
+	subtype, data, _, ok := ReadBinary(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return subtype, data
+}
+
+// BinaryOK is the same as Binary, except it returns a boolean instead of
+// panicking.
+func (v Value) BinaryOK() (subtype byte, data []byte, ok bool) {
+	if v.Type != bsontype.Binary {
+		return 0x00, nil, false
+	}
+	subtype, data, _, ok = ReadBinary(v.Data)
+	if !ok {
+		return 0x00, nil, false
+	}
+	return subtype, data, true
+}
+
+// ObjectID returns the BSON objectid value the Value represents. It panics if the value is a BSON
+// type other than objectid.
+func (v Value) ObjectID() primitive.ObjectID {
+	if v.Type != bsontype.ObjectID {
+		panic(ElementTypeError{"bsoncore.Value.ObjectID", v.Type})
+	}
+	oid, _, ok := ReadObjectID(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return oid
+}
+
+// ObjectIDOK is the same as ObjectID, except it returns a boolean instead of
+// panicking.
+func (v Value) ObjectIDOK() (primitive.ObjectID, bool) {
+	if v.Type != bsontype.ObjectID {
+		return primitive.ObjectID{}, false
+	}
+	oid, _, ok := ReadObjectID(v.Data)
+	if !ok {
+		return primitive.ObjectID{}, false
+	}
+	return oid, true
+}
+
+// Boolean returns the boolean value the Value represents. It panics if the
+// value is a BSON type other than boolean.
+func (v Value) Boolean() bool {
+	if v.Type != bsontype.Boolean {
+		panic(ElementTypeError{"bsoncore.Value.Boolean", v.Type})
+	}
+	b, _, ok := ReadBoolean(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return b
+}
+
+// BooleanOK is the same as Boolean, except it returns a boolean instead of
+// panicking.
+func (v Value) BooleanOK() (bool, bool) {
+	if v.Type != bsontype.Boolean {
+		return false, false
+	}
+	b, _, ok := ReadBoolean(v.Data)
+	if !ok {
+		return false, false
+	}
+	return b, true
+}
+
+// DateTime returns the BSON datetime value the Value represents as a
+// unix timestamp. It panics if the value is a BSON type other than datetime.
+func (v Value) DateTime() int64 {
+	if v.Type != bsontype.DateTime {
+		panic(ElementTypeError{"bsoncore.Value.DateTime", v.Type})
+	}
+	dt, _, ok := ReadDateTime(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return dt
+}
+
+// DateTimeOK is the same as DateTime, except it returns a boolean instead of
+// panicking.
+func (v Value) DateTimeOK() (int64, bool) {
+	if v.Type != bsontype.DateTime {
+		return 0, false
+	}
+	dt, _, ok := ReadDateTime(v.Data)
+	if !ok {
+		return 0, false
+	}
+	return dt, true
+}
+
+// Time returns the BSON datetime value the Value represents. It panics if the value is a BSON
+// type other than datetime.
+func (v Value) Time() time.Time {
+	if v.Type != bsontype.DateTime {
+		panic(ElementTypeError{"bsoncore.Value.Time", v.Type})
+	}
+	dt, _, ok := ReadDateTime(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return time.Unix(int64(dt)/1000, int64(dt)%1000*1000000)
+}
+
+// TimeOK is the same as Time, except it returns a boolean instead of
+// panicking.
+func (v Value) TimeOK() (time.Time, bool) {
+	if v.Type != bsontype.DateTime {
+		return time.Time{}, false
+	}
+	dt, _, ok := ReadDateTime(v.Data)
+	if !ok {
+		return time.Time{}, false
+	}
+	return time.Unix(int64(dt)/1000, int64(dt)%1000*1000000), true
+}
+
+// Regex returns the BSON regex value the Value represents. It panics if the value is a BSON
+// type other than regex.
+func (v Value) Regex() (pattern, options string) {
+	if v.Type != bsontype.Regex {
+		panic(ElementTypeError{"bsoncore.Value.Regex", v.Type})
+	}
+	pattern, options, _, ok := ReadRegex(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return pattern, options
+}
+
+// RegexOK is the same as Regex, except it returns a boolean instead of
+// panicking.
+func (v Value) RegexOK() (pattern, options string, ok bool) {
+	if v.Type != bsontype.Regex {
+		return "", "", false
+	}
+	pattern, options, _, ok = ReadRegex(v.Data)
+	if !ok {
+		return "", "", false
+	}
+	return pattern, options, true
+}
+
+// DBPointer returns the BSON dbpointer value the Value represents. It panics if the value is a BSON
+// type other than DBPointer.
+func (v Value) DBPointer() (string, primitive.ObjectID) {
+	if v.Type != bsontype.DBPointer {
+		panic(ElementTypeError{"bsoncore.Value.DBPointer", v.Type})
+	}
+	ns, pointer, _, ok := ReadDBPointer(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return ns, pointer
+}
+
+// DBPointerOK is the same as DBPoitner, except that it returns a boolean
+// instead of panicking.
+func (v Value) DBPointerOK() (string, primitive.ObjectID, bool) {
+	if v.Type != bsontype.DBPointer {
+		return "", primitive.ObjectID{}, false
+	}
+	ns, pointer, _, ok := ReadDBPointer(v.Data)
+	if !ok {
+		return "", primitive.ObjectID{}, false
+	}
+	return ns, pointer, true
+}
+
+// JavaScript returns the BSON JavaScript code value the Value represents. It panics if the value is
+// a BSON type other than JavaScript code.
+func (v Value) JavaScript() string {
+	if v.Type != bsontype.JavaScript {
+		panic(ElementTypeError{"bsoncore.Value.JavaScript", v.Type})
+	}
+	js, _, ok := ReadJavaScript(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return js
+}
+
+// JavaScriptOK is the same as Javascript, excepti that it returns a boolean
+// instead of panicking.
+func (v Value) JavaScriptOK() (string, bool) {
+	if v.Type != bsontype.JavaScript {
+		return "", false
+	}
+	js, _, ok := ReadJavaScript(v.Data)
+	if !ok {
+		return "", false
+	}
+	return js, true
+}
+
+// Symbol returns the BSON symbol value the Value represents. It panics if the value is a BSON
+// type other than symbol.
+func (v Value) Symbol() string {
+	if v.Type != bsontype.Symbol {
+		panic(ElementTypeError{"bsoncore.Value.Symbol", v.Type})
+	}
+	symbol, _, ok := ReadSymbol(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return symbol
+}
+
+// SymbolOK is the same as Symbol, excepti that it returns a boolean
+// instead of panicking.
+func (v Value) SymbolOK() (string, bool) {
+	if v.Type != bsontype.Symbol {
+		return "", false
+	}
+	symbol, _, ok := ReadSymbol(v.Data)
+	if !ok {
+		return "", false
+	}
+	return symbol, true
+}
+
+// CodeWithScope returns the BSON JavaScript code with scope the Value represents.
+// It panics if the value is a BSON type other than JavaScript code with scope.
+func (v Value) CodeWithScope() (string, Document) {
+	if v.Type != bsontype.CodeWithScope {
+		panic(ElementTypeError{"bsoncore.Value.CodeWithScope", v.Type})
+	}
+	code, scope, _, ok := ReadCodeWithScope(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return code, scope
+}
+
+// CodeWithScopeOK is the same as CodeWithScope, except that it returns a boolean instead of
+// panicking.
+func (v Value) CodeWithScopeOK() (string, Document, bool) {
+	if v.Type != bsontype.CodeWithScope {
+		return "", nil, false
+	}
+	code, scope, _, ok := ReadCodeWithScope(v.Data)
+	if !ok {
+		return "", nil, false
+	}
+	return code, scope, true
+}
+
+// Int32 returns the int32 the Value represents. It panics if the value is a BSON type other than
+// int32.
+func (v Value) Int32() int32 {
+	if v.Type != bsontype.Int32 {
+		panic(ElementTypeError{"bsoncore.Value.Int32", v.Type})
+	}
+	i32, _, ok := ReadInt32(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return i32
+}
+
+// Int32OK is the same as Int32, except that it returns a boolean instead of
+// panicking.
+func (v Value) Int32OK() (int32, bool) {
+	if v.Type != bsontype.Int32 {
+		return 0, false
+	}
+	i32, _, ok := ReadInt32(v.Data)
+	if !ok {
+		return 0, false
+	}
+	return i32, true
+}
+
+// Timestamp returns the BSON timestamp value the Value represents. It panics if the value is a
+// BSON type other than timestamp.
+func (v Value) Timestamp() (t, i uint32) {
+	if v.Type != bsontype.Timestamp {
+		panic(ElementTypeError{"bsoncore.Value.Timestamp", v.Type})
+	}
+	t, i, _, ok := ReadTimestamp(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return t, i
+}
+
+// TimestampOK is the same as Timestamp, except that it returns a boolean
+// instead of panicking.
+func (v Value) TimestampOK() (t, i uint32, ok bool) {
+	if v.Type != bsontype.Timestamp {
+		return 0, 0, false
+	}
+	t, i, _, ok = ReadTimestamp(v.Data)
+	if !ok {
+		return 0, 0, false
+	}
+	return t, i, true
+}
+
+// Int64 returns the int64 the Value represents. It panics if the value is a BSON type other than
+// int64.
+func (v Value) Int64() int64 {
+	if v.Type != bsontype.Int64 {
+		panic(ElementTypeError{"bsoncore.Value.Int64", v.Type})
+	}
+	i64, _, ok := ReadInt64(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return i64
+}
+
+// Int64OK is the same as Int64, except that it returns a boolean instead of
+// panicking.
+func (v Value) Int64OK() (int64, bool) {
+	if v.Type != bsontype.Int64 {
+		return 0, false
+	}
+	i64, _, ok := ReadInt64(v.Data)
+	if !ok {
+		return 0, false
+	}
+	return i64, true
+}
+
+// Decimal128 returns the decimal the Value represents. It panics if the value is a BSON type other than
+// decimal.
+func (v Value) Decimal128() primitive.Decimal128 {
+	if v.Type != bsontype.Decimal128 {
+		panic(ElementTypeError{"bsoncore.Value.Decimal128", v.Type})
+	}
+	d128, _, ok := ReadDecimal128(v.Data)
+	if !ok {
+		panic(NewInsufficientBytesError(v.Data, v.Data))
+	}
+	return d128
+}
+
+// Decimal128OK is the same as Decimal128, except that it returns a boolean
+// instead of panicking.
+func (v Value) Decimal128OK() (primitive.Decimal128, bool) {
+	if v.Type != bsontype.Decimal128 {
+		return primitive.Decimal128{}, false
+	}
+	d128, _, ok := ReadDecimal128(v.Data)
+	if !ok {
+		return primitive.Decimal128{}, false
+	}
+	return d128, true
+}
+
+var hexChars = "0123456789abcdef"
+
+func escapeString(s string) string {
+	escapeHTML := true
+	var buf bytes.Buffer
+	buf.WriteByte('"')
+	start := 0
+	for i := 0; i < len(s); {
+		if b := s[i]; b < utf8.RuneSelf {
+			if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
+				i++
+				continue
+			}
+			if start < i {
+				buf.WriteString(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				buf.WriteByte('\\')
+				buf.WriteByte(b)
+			case '\n':
+				buf.WriteByte('\\')
+				buf.WriteByte('n')
+			case '\r':
+				buf.WriteByte('\\')
+				buf.WriteByte('r')
+			case '\t':
+				buf.WriteByte('\\')
+				buf.WriteByte('t')
+			case '\b':
+				buf.WriteByte('\\')
+				buf.WriteByte('b')
+			case '\f':
+				buf.WriteByte('\\')
+				buf.WriteByte('f')
+			default:
+				// This encodes bytes < 0x20 except for \t, \n and \r.
+				// If escapeHTML is set, it also escapes <, >, and &
+				// because they can lead to security holes when
+				// user-controlled strings are rendered into JSON
+				// and served to some browsers.
+				buf.WriteString(`\u00`)
+				buf.WriteByte(hexChars[b>>4])
+				buf.WriteByte(hexChars[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRuneInString(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				buf.WriteString(s[start:i])
+			}
+			buf.WriteString(`\ufffd`)
+			i += size
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR.
+		// U+2029 is PARAGRAPH SEPARATOR.
+		// They are both technically valid characters in JSON strings,
+		// but don't work in JSONP, which has to be evaluated as JavaScript,
+		// and can lead to security holes there. It is valid JSON to
+		// escape them, so we do so unconditionally.
+		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				buf.WriteString(s[start:i])
+			}
+			buf.WriteString(`\u202`)
+			buf.WriteByte(hexChars[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		buf.WriteString(s[start:])
+	}
+	buf.WriteByte('"')
+	return buf.String()
+}
+
+func formatDouble(f float64) string {
+	var s string
+	if math.IsInf(f, 1) {
+		s = "Infinity"
+	} else if math.IsInf(f, -1) {
+		s = "-Infinity"
+	} else if math.IsNaN(f) {
+		s = "NaN"
+	} else {
+		// Print exactly one decimalType place for integers; otherwise, print as many are necessary to
+		// perfectly represent it.
+		s = strconv.FormatFloat(f, 'G', -1, 64)
+		if !strings.ContainsRune(s, '.') {
+			s += ".0"
+		}
+	}
+
+	return s
+}
+
+type sortableString []rune
+
+func (ss sortableString) Len() int {
+	return len(ss)
+}
+
+func (ss sortableString) Less(i, j int) bool {
+	return ss[i] < ss[j]
+}
+
+func (ss sortableString) Swap(i, j int) {
+	oldI := ss[i]
+	ss[i] = ss[j]
+	ss[j] = oldI
+}
+
+func sortStringAlphebeticAscending(s string) string {
+	ss := sortableString([]rune(s))
+	sort.Sort(ss)
+	return string([]rune(ss))
+}
+
+func docAsArray(d Document, debug bool) string {
+	if len(d) < 5 {
+		return ""
+	}
+	var buf bytes.Buffer
+	buf.WriteByte('[')
+
+	length, rem, _ := ReadLength(d) // We know we have enough bytes to read the length
+
+	length -= 4
+
+	var elem Element
+	var ok bool
+	first := true
+	for length > 1 {
+		if !first {
+			buf.WriteByte(',')
+		}
+		elem, rem, ok = ReadElement(rem)
+		length -= int32(len(elem))
+		if !ok {
+			return ""
+		}
+		if debug {
+			fmt.Fprintf(&buf, "%s ", elem.Value().DebugString())
+		} else {
+			fmt.Fprintf(&buf, "%s", elem.Value())
+		}
+		first = false
+	}
+	buf.WriteByte(']')
+
+	return buf.String()
+}
