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()
+}
