From 02a0cf2ab54da6c56a7d7e2a24c4fb39708b21ee Mon Sep 17 00:00:00 2001
From: Valeri Karpov <val@karpov.io>
Date: Mon, 27 May 2024 15:26:03 -0400
Subject: [PATCH 1/7] refactor(document): clean up transform option handling

---
 lib/document.js | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lib/document.js b/lib/document.js
index 6cce70c486..71511b37a9 100644
--- a/lib/document.js
+++ b/lib/document.js
@@ -3799,7 +3799,6 @@ Document.prototype.$__handleReject = function handleReject(err) {
 
 Document.prototype.$toObject = function(options, json) {
   const defaultOptions = {
-    transform: true,
     flattenDecimals: true
   };
 
@@ -3858,6 +3857,7 @@ Document.prototype.$toObject = function(options, json) {
     _seen: (options && options._seen) || new Map(),
     _calledWithOptions: options._calledWithOptions
   };
+  delete cloneOptions.transform;
 
   const depopulate = options.depopulate ||
     (options._parentOptions && options._parentOptions.depopulate || false);
@@ -3882,7 +3882,7 @@ Document.prototype.$toObject = function(options, json) {
   cloneOptions._skipSingleNestedGetters = false;
   // remember the root transform function
   // to save it from being overwritten by sub-transform functions
-  const originalTransform = options.transform;
+  //const originalTransform = options.transform;
 
   let ret = clone(this._doc, cloneOptions) || {};
 
@@ -3903,7 +3903,7 @@ Document.prototype.$toObject = function(options, json) {
     delete ret[this.$__schema.options.versionKey];
   }
 
-  let transform = options.transform;
+  let transform = options._calledWithOptions.transform ?? options.transform ?? true;
 
   // In the case where a subdocument has its own transform function, we need to
   // check and see if the parent has a transform (options.transform) and if the
@@ -3925,7 +3925,7 @@ Document.prototype.$toObject = function(options, json) {
       transform = (typeof options.transform === 'function' ? options.transform : opts.transform);
     }
   } else {
-    options.transform = originalTransform;
+    //options.transform = originalTransform;
   }
 
   if (typeof transform === 'function') {
@@ -4146,7 +4146,8 @@ function applyVirtuals(self, json, options, toObjectOptions) {
       assignPath = path.substring(options.path.length + 1);
     }
     if (assignPath.indexOf('.') === -1 && assignPath === path) {
-      v = clone(self.get(path, { noDottedPath: true }), options);
+      v = self.get(path, { noDottedPath: true });
+      v = clone(v, options);
       if (v === void 0) {
         continue;
       }

From 50ce3f384f5bd764aa02b62d9b4167518fda2f3c Mon Sep 17 00:00:00 2001
From: Valeri Karpov <val@karpov.io>
Date: Mon, 27 May 2024 16:05:15 -0400
Subject: [PATCH 2/7] perf: avoid creating separate cloneOptions re: #14394

---
 lib/document.js       | 52 +++++++++++++++++++++----------------------
 test/document.test.js | 22 ++++++++++++------
 2 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/lib/document.js b/lib/document.js
index 71511b37a9..0846e0d928 100644
--- a/lib/document.js
+++ b/lib/document.js
@@ -3847,20 +3847,15 @@ Document.prototype.$toObject = function(options, json) {
   // `clone()` will recursively call `$toObject()` on embedded docs, so we
   // need the original options the user passed in, plus `_isNested` and
   // `_parentOptions` for checking whether we need to depopulate.
-  const cloneOptions = {
-    ...options,
-    _isNested: true,
-    json: json,
-    minimize: _minimize,
-    flattenMaps: flattenMaps,
-    flattenObjectIds: flattenObjectIds,
-    _seen: (options && options._seen) || new Map(),
-    _calledWithOptions: options._calledWithOptions
-  };
-  delete cloneOptions.transform;
+  const cloneOptions = options;
+
+  options.minimize = _minimize;
+  options._seen = options._seen || new Map();
 
-  const depopulate = options.depopulate ||
-    (options._parentOptions && options._parentOptions.depopulate || false);
+  const depopulate = options._calledWithOptions.depopulate
+    ?? options._parentOptions?.depopulate
+    ?? defaultOptions.depopulate
+    ?? false;
   // _isNested will only be true if this is not the top level document, we
   // should never depopulate the top-level document
   if (depopulate && options._isNested && this.$__.wasPopulated) {
@@ -3895,7 +3890,14 @@ Document.prototype.$toObject = function(options, json) {
     }
   }
 
-  if (options.virtuals || (options.getters && options.virtuals !== false)) {
+  const getters = options._calledWithOptions.getters
+    ?? defaultOptions.getters
+    ?? false;
+  const virtuals = options._calledWithOptions.virtuals
+    ?? defaultOptions.virtuals
+    ?? undefined;
+
+  if (virtuals || (getters && virtuals !== false)) {
     applyVirtuals(this, ret, cloneOptions, options);
   }
 
@@ -3903,7 +3905,13 @@ Document.prototype.$toObject = function(options, json) {
     delete ret[this.$__schema.options.versionKey];
   }
 
-  let transform = options._calledWithOptions.transform ?? options.transform ?? true;
+  let transform = options._calledWithOptions.transform ?? true;
+  let transformFunction = undefined;
+  if (transform === true) {
+    transformFunction = defaultOptions.transform;
+  } else if (typeof transform === 'function') {
+    transformFunction = transform;
+  }
 
   // In the case where a subdocument has its own transform function, we need to
   // check and see if the parent has a transform (options.transform) and if the
@@ -3918,18 +3926,8 @@ Document.prototype.$toObject = function(options, json) {
     omitDeselectedFields(this, ret);
   }
 
-  if (transform === true || (schemaOptions.toObject && transform)) {
-    const opts = options.json ? schemaOptions.toJSON : schemaOptions.toObject;
-
-    if (opts) {
-      transform = (typeof options.transform === 'function' ? options.transform : opts.transform);
-    }
-  } else {
-    //options.transform = originalTransform;
-  }
-
-  if (typeof transform === 'function') {
-    const xformed = transform(this, ret, options);
+  if (typeof transformFunction === 'function') {
+    const xformed = transformFunction(this, ret, options);
     if (typeof xformed !== 'undefined') {
       ret = xformed;
     }
diff --git a/test/document.test.js b/test/document.test.js
index 066699766f..e5dcfa3bb1 100644
--- a/test/document.test.js
+++ b/test/document.test.js
@@ -711,11 +711,6 @@ describe('document', function() {
         name: String,
         email: String
       });
-      const topicSchema = new Schema({
-        title: String,
-        email: String,
-        followers: [userSchema]
-      });
 
       userSchema.options.toObject = {
         transform: function(doc, ret) {
@@ -723,6 +718,12 @@ describe('document', function() {
         }
       };
 
+      const topicSchema = new Schema({
+        title: String,
+        email: String,
+        followers: [userSchema]
+      });
+
       topicSchema.options.toObject = {
         transform: function(doc, ret) {
           ret.title = ret.title.toLowerCase();
@@ -833,7 +834,10 @@ describe('document', function() {
       const userSchema = Schema({
         firstName: String,
         company: {
-          type: { companyId: { type: Schema.Types.ObjectId }, companyName: String }
+          type: {
+            companyId: { type: Schema.Types.ObjectId },
+            companyName: String
+          }
         }
       }, {
         toObject: {
@@ -849,6 +853,7 @@ describe('document', function() {
 
       const User = db.model('User', userSchema);
       const user = new User({ firstName: 'test', company: { companyName: 'foo' } });
+      assert.equal(transformCalls.length, 0);
       const obj = user.toObject();
       assert.strictEqual(obj.company.details, 42);
       assert.equal(transformCalls.length, 1);
@@ -1045,7 +1050,10 @@ describe('document', function() {
       const userSchema = Schema({
         firstName: String,
         company: {
-          type: { companyId: { type: Schema.Types.ObjectId }, companyName: String }
+          type: {
+            companyId: { type: Schema.Types.ObjectId },
+            companyName: String
+          }
         }
       }, {
         id: false,

From 5d185b9ff079beff4aedf45c3e3a6fa53c3bf203 Mon Sep 17 00:00:00 2001
From: Valeri Karpov <val@karpov.io>
Date: Thu, 30 May 2024 15:55:05 -0400
Subject: [PATCH 3/7] perf: remove some more unnecessary cloning in $toObject()
 and correct options to get()

Re: #14394
---
 lib/document.js            | 59 +++++++++++---------------------------
 lib/helpers/clone.js       |  2 +-
 test/helpers/clone.test.js |  2 +-
 3 files changed, 18 insertions(+), 45 deletions(-)

diff --git a/lib/document.js b/lib/document.js
index 0846e0d928..bdb6e2e57d 100644
--- a/lib/document.js
+++ b/lib/document.js
@@ -3798,10 +3798,6 @@ Document.prototype.$__handleReject = function handleReject(err) {
  */
 
 Document.prototype.$toObject = function(options, json) {
-  const defaultOptions = {
-    flattenDecimals: true
-  };
-
   const path = json ? 'toJSON' : 'toObject';
   const baseOptions = this.constructor &&
     this.constructor.base &&
@@ -3810,7 +3806,7 @@ Document.prototype.$toObject = function(options, json) {
   const schemaOptions = this.$__schema && this.$__schema.options || {};
   // merge base default options with Schema's set default options if available.
   // `clone` is necessary here because `utils.options` directly modifies the second input.
-  Object.assign(defaultOptions, baseOptions, schemaOptions[path]);
+  const defaultOptions = Object.assign({}, baseOptions, schemaOptions[path]);
 
   // If options do not exist or is not an object, set it to empty object
   options = utils.isPOJO(options) ? { ...options } : {};
@@ -3825,30 +3821,6 @@ Document.prototype.$toObject = function(options, json) {
     _minimize = schemaOptions.minimize;
   }
 
-  let flattenMaps;
-  if (options._calledWithOptions.flattenMaps != null) {
-    flattenMaps = options.flattenMaps;
-  } else if (defaultOptions.flattenMaps != null) {
-    flattenMaps = defaultOptions.flattenMaps;
-  } else {
-    flattenMaps = schemaOptions.flattenMaps;
-  }
-
-  let flattenObjectIds;
-  if (options._calledWithOptions.flattenObjectIds != null) {
-    flattenObjectIds = options.flattenObjectIds;
-  } else if (defaultOptions.flattenObjectIds != null) {
-    flattenObjectIds = defaultOptions.flattenObjectIds;
-  } else {
-    flattenObjectIds = schemaOptions.flattenObjectIds;
-  }
-
-  // The original options that will be passed to `clone()`. Important because
-  // `clone()` will recursively call `$toObject()` on embedded docs, so we
-  // need the original options the user passed in, plus `_isNested` and
-  // `_parentOptions` for checking whether we need to depopulate.
-  const cloneOptions = options;
-
   options.minimize = _minimize;
   options._seen = options._seen || new Map();
 
@@ -3859,7 +3831,7 @@ Document.prototype.$toObject = function(options, json) {
   // _isNested will only be true if this is not the top level document, we
   // should never depopulate the top-level document
   if (depopulate && options._isNested && this.$__.wasPopulated) {
-    return clone(this.$__.wasPopulated.value || this._id, cloneOptions);
+    return clone(this.$__.wasPopulated.value || this._id, options);
   }
 
   // merge default options with input options.
@@ -3872,40 +3844,41 @@ Document.prototype.$toObject = function(options, json) {
   options.json = json;
   options.minimize = _minimize;
 
-  cloneOptions._parentOptions = options;
+  options._parentOptions = options;
 
-  cloneOptions._skipSingleNestedGetters = false;
+  options._skipSingleNestedGetters = false;
   // remember the root transform function
   // to save it from being overwritten by sub-transform functions
-  //const originalTransform = options.transform;
+  // const originalTransform = options.transform;
 
-  let ret = clone(this._doc, cloneOptions) || {};
+  let ret = clone(this._doc, options) || {};
 
-  cloneOptions._skipSingleNestedGetters = true;
-  if (options.getters) {
-    applyGetters(this, ret, cloneOptions);
+  options._skipSingleNestedGetters = true;
+  const getters = options._calledWithOptions.getters
+    ?? options.getters
+    ?? defaultOptions.getters
+    ?? false;
+  if (getters) {
+    applyGetters(this, ret, options);
 
     if (options.minimize) {
       ret = minimize(ret) || {};
     }
   }
 
-  const getters = options._calledWithOptions.getters
-    ?? defaultOptions.getters
-    ?? false;
   const virtuals = options._calledWithOptions.virtuals
     ?? defaultOptions.virtuals
     ?? undefined;
 
   if (virtuals || (getters && virtuals !== false)) {
-    applyVirtuals(this, ret, cloneOptions, options);
+    applyVirtuals(this, ret, options, options);
   }
 
   if (options.versionKey === false && this.$__schema.options.versionKey) {
     delete ret[this.$__schema.options.versionKey];
   }
 
-  let transform = options._calledWithOptions.transform ?? true;
+  const transform = options._calledWithOptions.transform ?? true;
   let transformFunction = undefined;
   if (transform === true) {
     transformFunction = defaultOptions.transform;
@@ -4144,7 +4117,7 @@ function applyVirtuals(self, json, options, toObjectOptions) {
       assignPath = path.substring(options.path.length + 1);
     }
     if (assignPath.indexOf('.') === -1 && assignPath === path) {
-      v = self.get(path, { noDottedPath: true });
+      v = self.get(path, null, { noDottedPath: true });
       v = clone(v, options);
       if (v === void 0) {
         continue;
diff --git a/lib/helpers/clone.js b/lib/helpers/clone.js
index a7b5f2f2fe..fafb2f3063 100644
--- a/lib/helpers/clone.js
+++ b/lib/helpers/clone.js
@@ -40,7 +40,7 @@ function clone(obj, options, isArrayChild) {
       // Single nested subdocs should apply getters later in `applyGetters()`
       // when calling `toObject()`. See gh-7442, gh-8295
       if (options._skipSingleNestedGetters && obj.$isSingleNested) {
-        options = Object.assign({}, options, { getters: false });
+        options._calledWithOptions = Object.assign({}, options._calledWithOptions || {}, { getters: false });
       }
       if (options.retainDocuments && obj.$__ != null) {
         const clonedDoc = obj.$clone();
diff --git a/test/helpers/clone.test.js b/test/helpers/clone.test.js
index 7d84a5ed03..80540041c2 100644
--- a/test/helpers/clone.test.js
+++ b/test/helpers/clone.test.js
@@ -88,7 +88,7 @@ describe('clone', () => {
         $isSingleNested: true,
         toObject(cloneOpts) {
           assert.deepStrictEqual(
-            Object.assign({}, baseOpts, { getters: false }),
+            Object.assign({}, baseOpts),
             cloneOpts
           );
           const obj = JSON.parse(JSON.stringify(base));

From 1c7cf1740d9b0c0ddde77f94537732d9e2a9ebf4 Mon Sep 17 00:00:00 2001
From: Valeri Karpov <val@karpov.io>
Date: Fri, 31 May 2024 10:18:34 -0400
Subject: [PATCH 4/7] remove old benchmarks, add new benchmark for #14394

---
 benchmarks/benchjs/casting.js    |  151 ---
 benchmarks/benchjs/delete.js     |  136 ---
 benchmarks/benchjs/insert.js     |  189 ---
 benchmarks/benchjs/multiop.js    |  482 --------
 benchmarks/benchjs/population.js |  410 -------
 benchmarks/benchjs/read.js       |  319 -----
 benchmarks/bigboard.json         | 1909 ------------------------------
 benchmarks/clone.js              |   79 --
 benchmarks/create.js             |   46 -
 benchmarks/index.js              |  151 ---
 benchmarks/mapOfSubdocs.js       |    5 +-
 benchmarks/mem.js                |  165 ---
 benchmarks/populate.js           |   84 --
 benchmarks/recursiveToObject.js  |   60 +
 benchmarks/validate.js           |   68 --
 15 files changed, 61 insertions(+), 4193 deletions(-)
 delete mode 100644 benchmarks/benchjs/casting.js
 delete mode 100644 benchmarks/benchjs/delete.js
 delete mode 100644 benchmarks/benchjs/insert.js
 delete mode 100644 benchmarks/benchjs/multiop.js
 delete mode 100644 benchmarks/benchjs/population.js
 delete mode 100644 benchmarks/benchjs/read.js
 delete mode 100644 benchmarks/bigboard.json
 delete mode 100644 benchmarks/clone.js
 delete mode 100644 benchmarks/create.js
 delete mode 100644 benchmarks/index.js
 delete mode 100644 benchmarks/mem.js
 delete mode 100644 benchmarks/populate.js
 create mode 100644 benchmarks/recursiveToObject.js
 delete mode 100644 benchmarks/validate.js

diff --git a/benchmarks/benchjs/casting.js b/benchmarks/benchjs/casting.js
deleted file mode 100644
index f7027eed6b..0000000000
--- a/benchmarks/benchjs/casting.js
+++ /dev/null
@@ -1,151 +0,0 @@
-'use strict';
-const mongoose = require('../../lib');
-const Benchmark = require('benchmark');
-
-const suite = new Benchmark.Suite();
-
-const Schema = mongoose.Schema;
-const ObjectId = Schema.Types.ObjectId;
-const utils = require('../../lib/utils.js');
-
-// to make things work in the way the are normally described online...
-/*
- *global.Schema = Schema;
- *global.mongoose = mongoose;
- */
-
-/**
- * These are all the benchmark tests for casting stuff
- */
-
-const Comments = new Schema();
-
-Comments.add({
-  title: String,
-  date: Date,
-  body: String,
-  comments: [Comments],
-});
-
-const BlogPost = new Schema({
-  title: String,
-  author: String,
-  slug: String,
-  date: Date,
-  meta: {
-    date: Date,
-    visitors: Number,
-  },
-  published: Boolean,
-  mixed: {},
-  numbers: [Number],
-  tags: [String],
-  owners: [ObjectId],
-  comments: [Comments],
-  def: {
-    type: String,
-    default: 'kandinsky',
-  },
-});
-
-const commentData = {
-  title: 'test comment',
-  date: new Date(),
-  body: 'this be some crazzzyyyyy text that would go in a comment',
-  comments: [{ title: 'second level', date: new Date(), body: 'texttt' }],
-};
-
-const blogData = {
-  title: 'dummy post',
-  author: 'somebody',
-  slug: 'test.post',
-  date: new Date(),
-  meta: {
-    date: new Date(),
-    visitors: 9001,
-  },
-  published: true,
-  mixed: {
-    thisIsRandom: true,
-  },
-  numbers: [1, 2, 7, 10, 23432],
-  tags: ['test', 'BENCH', 'things', 'more things'],
-  def: 'THANGS!!!',
-  comments: [],
-};
-
-const blogData10 = utils.clone(blogData);
-const blogData100 = utils.clone(blogData);
-const blogData1000 = utils.clone(blogData);
-const blogData10000 = utils.clone(blogData);
-
-for (let i = 0; i < 10; i++) {
-  blogData10.comments.push(commentData);
-}
-for (let i = 0; i < 100; i++) {
-  blogData100.comments.push(commentData);
-}
-for (let i = 0; i < 1000; i++) {
-  blogData1000.comments.push(commentData);
-}
-for (let i = 0; i < 10000; i++) {
-  blogData10000.comments.push(commentData);
-}
-
-mongoose.model('BlogPost', BlogPost);
-
-suite
-  .add('Casting - Embedded Docs - 0 Docs', {
-    fn: function () {
-      const BlogPost = mongoose.model('BlogPost');
-      const bp = new BlogPost();
-      bp.init(blogData);
-    },
-  })
-  .add('Casting - Embedded Docs - 10 Docs', {
-    fn: function () {
-      const BlogPost = mongoose.model('BlogPost');
-      const bp = new BlogPost();
-      bp.init(blogData10);
-    },
-  })
-  .add('Casting - Embedded Docs - 100 Docs', {
-    fn: function () {
-      const BlogPost = mongoose.model('BlogPost');
-      const bp = new BlogPost();
-      bp.init(blogData100);
-    },
-  })
-  .add('Casting - Embedded Docs - 1000 Docs', {
-    fn: function () {
-      const BlogPost = mongoose.model('BlogPost');
-      const bp = new BlogPost();
-      bp.init(blogData1000);
-    },
-  })
-  .add('Casting - Embedded Docs - 10000 Docs', {
-    fn: function () {
-      const BlogPost = mongoose.model('BlogPost');
-      const bp = new BlogPost();
-      bp.init(blogData10000);
-    },
-  })
-  .on('cycle', function (evt) {
-    if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-      console.log(String(evt.target));
-    }
-  })
-  .on('complete', function () {
-    if (!process.env.MONGOOSE_DEV && !process.env.PULL_REQUEST) {
-      const outObj = {};
-      this.forEach(function (item) {
-        const out = {};
-        out.stats = item.stats;
-        delete out.stats.sample;
-        out.ops = item.hz;
-        outObj[item.name.replace(/\s/g, '')] = out;
-      });
-      console.dir(outObj, { depth: null, colors: true });
-    }
-  })
-  .run({ async: true });
diff --git a/benchmarks/benchjs/delete.js b/benchmarks/benchjs/delete.js
deleted file mode 100644
index 1d717f7f6e..0000000000
--- a/benchmarks/benchjs/delete.js
+++ /dev/null
@@ -1,136 +0,0 @@
-'use strict';
-const mongoose = require('../../lib');
-const Benchmark = require('benchmark');
-
-const suite = new Benchmark.Suite();
-
-const Schema = mongoose.Schema;
-const mongoClient = require('mongodb').MongoClient;
-
-// to make things work in the way the are normally described online...
-/*
- *global.Schema = Schema;
- *global.mongoose = mongoose;
- */
-
-/**
- * These are all the benchmark tests for deleting data
- */
-
-mongoose.connect('mongodb://127.0.0.1/mongoose-bench', function (err) {
-  if (err) {
-    throw err;
-  }
-  mongoClient.connect('mongodb://127.0.0.1', function (err, client) {
-    if (err) {
-      throw err;
-    }
-
-    const db = client.db('mongoose-bench');
-
-    const UserSchema = new Schema({
-      name: String,
-      age: Number,
-      likes: [String],
-      address: String,
-    });
-
-    const User = mongoose.model('User', UserSchema);
-    const user = db.collection('user');
-
-    const mIds = [];
-    const dIds = [];
-
-    const data = {
-      name: 'name',
-      age: 0,
-      likes: ['dogs', 'cats', 'pizza'],
-      address: ' Nowhere-ville USA',
-    };
-
-    // insert all of the data here
-    let count = 1000;
-    for (let i = 0; i < 500; i++) {
-      User.create(data, function (err, u) {
-        if (err) {
-          throw err;
-        }
-        mIds.push(u.id);
-        --count || next();
-      });
-      const nData = {};
-      nData.name = data.name;
-      nData.age = data.age;
-      nData.likes = data.likes;
-      nData.address = data.address;
-      user.insertOne(nData, function (err, res) {
-        dIds.push(res.insertedId);
-        --count || next();
-      });
-    }
-
-    function closeDB() {
-      User.count(function (err, res) {
-        if (res !== 0) {
-          console.log('Still mongoose entries left...');
-        }
-        mongoose.disconnect();
-      });
-      user.count({}, function (err, res) {
-        if (res !== 0) {
-          console.log('Still driver entries left...');
-        }
-        if (err) {
-          throw err;
-        }
-        client.close();
-      });
-    }
-
-    suite
-      .add('Delete - Mongoose', {
-        defer: true,
-        fn: function (deferred) {
-          User.remove({ _id: mIds.pop() }, function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Delete - Driver', {
-        defer: true,
-        fn: function (deferred) {
-          user.deleteOne({ _id: dIds.pop() }, function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .on('cycle', function (evt) {
-        if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-          console.log(String(evt.target));
-        }
-      })
-      .on('complete', function () {
-        closeDB();
-        if (!process.env.MONGOOSE_DEV && !process.env.PULL_REQUEST) {
-          const outObj = {};
-          this.forEach(function (item) {
-            const out = {};
-            out.stats = item.stats;
-            delete out.stats.sample;
-            out.ops = item.hz;
-            outObj[item.name.replace(/\s/g, '')] = out;
-          });
-          console.dir(outObj, { depth: null, colors: true });
-        }
-      });
-    function next() {
-      suite.run({ async: true });
-    }
-  });
-});
diff --git a/benchmarks/benchjs/insert.js b/benchmarks/benchjs/insert.js
deleted file mode 100644
index cd01bfb606..0000000000
--- a/benchmarks/benchjs/insert.js
+++ /dev/null
@@ -1,189 +0,0 @@
-'use strict';
-const mongoose = require('../../lib');
-const Benchmark = require('benchmark');
-
-const suite = new Benchmark.Suite();
-
-const Schema = mongoose.Schema;
-const mongoClient = require('mongodb').MongoClient;
-const utils = require('../../lib/utils.js');
-const ObjectId = Schema.Types.ObjectId;
-
-// to make things work in the way the are normally described online...
-/*
- *global.Schema = Schema;
- *global.mongoose = mongoose;
- */
-
-/**
- * These are all the benchmark tests for inserting data
- */
-
-mongoose.connect('mongodb://127.0.0.1/mongoose-bench', function (err) {
-  if (err) {
-    throw err;
-  }
-  mongoClient.connect(
-    'mongodb://127.0.0.1/mongoose-bench',
-    function (err, client) {
-      if (err) {
-        throw err;
-      }
-
-      const db = client.db('mongoose-bench');
-
-      const Comments = new Schema();
-      Comments.add({
-        title: String,
-        date: Date,
-        body: String,
-        comments: [Comments],
-      });
-
-      let BlogPost = new Schema({
-        title: String,
-        author: String,
-        slug: String,
-        date: Date,
-        meta: {
-          date: Date,
-          visitors: Number,
-        },
-        published: Boolean,
-        mixed: {},
-        numbers: [Number],
-        tags: [String],
-        owners: [ObjectId],
-        comments: [Comments],
-        def: {
-          type: String,
-          default: 'kandinsky',
-        },
-      });
-
-      const blogData = {
-        title: 'dummy post',
-        author: 'somebody',
-        slug: 'test.post',
-        date: new Date(),
-        meta: { date: new Date(), visitors: 9001 },
-        published: true,
-        mixed: { thisIsRandom: true },
-        numbers: [1, 2, 7, 10, 23432],
-        tags: ['test', 'BENCH', 'things', 'more things'],
-        def: 'THANGS!!!',
-        comments: [],
-      };
-      const commentData = {
-        title: 'test comment',
-        date: new Date(),
-        body: 'this be some crazzzyyyyy text that would go in a comment',
-        comments: [
-          {
-            title: 'second level',
-            date: new Date(),
-            body: 'texttt',
-          },
-        ],
-      };
-      for (let i = 0; i < 5; i++) {
-        blogData.comments.push(commentData);
-      }
-      const data = {
-        name: 'name',
-        age: 0,
-        likes: ['dogs', 'cats', 'pizza'],
-        address: ' Nowhere-ville USA',
-      };
-
-      const UserSchema = new Schema({
-        name: String,
-        age: Number,
-        likes: [String],
-        address: String,
-      });
-
-      const User = mongoose.model('User', UserSchema);
-      BlogPost = mongoose.model('BlogPost', BlogPost);
-      const user = db.collection('user');
-      const blogpost = db.collection('blogpost');
-
-      function closeDB() {
-        mongoose.connection.db.dropDatabase(function () {
-          mongoose.disconnect();
-          process.exit();
-        });
-      }
-
-      suite
-        .add('Insert - Mongoose - Basic', {
-          defer: true,
-          fn: function (deferred) {
-            const nData = utils.clone(data);
-            User.create(nData, function (err) {
-              if (err) {
-                throw err;
-              }
-              deferred.resolve();
-            });
-          },
-        })
-        .add('Insert - Driver - Basic', {
-          defer: true,
-          fn: function (deferred) {
-            const nData = utils.clone(data);
-            user.insertOne(nData, function (err) {
-              if (err) {
-                throw err;
-              }
-              deferred.resolve();
-            });
-          },
-        })
-        .add('Insert - Mongoose - Embedded Docs', {
-          defer: true,
-          fn: function (deferred) {
-            const bp = utils.clone(blogData);
-            BlogPost.create(bp, function (err) {
-              if (err) {
-                throw err;
-              }
-              deferred.resolve();
-            });
-          },
-        })
-        .add('Insert - Driver - Embedded Docs', {
-          defer: true,
-          fn: function (deferred) {
-            const bp = utils.clone(blogData);
-            blogpost.insertOne(bp, function (err) {
-              if (err) {
-                throw err;
-              }
-              deferred.resolve();
-            });
-          },
-        })
-        .on('cycle', function (evt) {
-          if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-            console.log(String(evt.target));
-          }
-        })
-        .on('complete', function () {
-          closeDB();
-          if (!process.env.MONGOOSE_DEV && !process.env.PULL_REQUEST) {
-            const outObj = {};
-            this.forEach(function (item) {
-              const out = {};
-              out.stats = item.stats;
-              delete out.stats.sample;
-              out.ops = item.hz;
-              outObj[item.name.replace(/\s/g, '')] = out;
-            });
-            console.dir(outObj, { depth: null, colors: true });
-          }
-        })
-        .run({ async: true });
-    }
-  );
-});
diff --git a/benchmarks/benchjs/multiop.js b/benchmarks/benchjs/multiop.js
deleted file mode 100644
index c3f73d1f73..0000000000
--- a/benchmarks/benchjs/multiop.js
+++ /dev/null
@@ -1,482 +0,0 @@
-'use strict';
-const mongoose = require('../../lib');
-const Benchmark = require('benchmark');
-
-const suite = new Benchmark.Suite();
-
-const Schema = mongoose.Schema;
-const ObjectId = Schema.Types.ObjectId;
-const mongoClient = require('mongodb').MongoClient;
-const utils = require('../../lib/utils.js');
-
-// to make things work in the way the are normally described online...
-/*
- *global.Schema = Schema;
- *global.mongoose = mongoose;
- */
-
-/**
- * These are all the benchmark tests for mixed data operations
- */
-
-mongoose.connect('mongodb://127.0.0.1/mongoose-bench', function (err) {
-  if (err) {
-    throw err;
-  }
-  mongoClient.connect('mongodb://127.0.0.1', function (err, client) {
-    if (err) {
-      throw err;
-    }
-
-    const db = client.db('mongoose-bench');
-
-    const Comments = new Schema();
-    Comments.add({
-      title: String,
-      date: Date,
-      body: String,
-      comments: [Comments],
-    });
-
-    let BlogPost = new Schema({
-      title: String,
-      author: String,
-      slug: String,
-      date: Date,
-      meta: {
-        date: Date,
-        visitors: Number,
-      },
-      published: Boolean,
-      mixed: {},
-      numbers: [Number],
-      tags: [String],
-      owners: [ObjectId],
-      comments: [Comments],
-      def: { type: String, default: 'kandinsky' },
-    });
-
-    const blogData = {
-      title: 'dummy post',
-      author: 'somebody',
-      slug: 'test.post',
-      date: new Date(),
-      meta: {
-        date: new Date(),
-        visitors: 9001,
-      },
-      published: true,
-      mixed: {
-        thisIsRandom: true,
-      },
-      numbers: [1, 2, 7, 10, 23432],
-      tags: ['test', 'BENCH', 'things', 'more things'],
-      def: 'THANGS!!!',
-      comments: [],
-    };
-    const commentData = {
-      title: 'test comment',
-      date: new Date(),
-      body: 'this be some crazzzyyyyy text that would go in a comment',
-      comments: [
-        {
-          title: 'second level',
-          date: new Date(),
-          body: 'texttt',
-        },
-      ],
-    };
-    for (let i = 0; i < 5; i++) {
-      blogData.comments.push(commentData);
-    }
-    const UserSchema = new Schema({
-      name: String,
-      age: Number,
-      likes: [String],
-      address: String,
-    });
-
-    const User = mongoose.model('User', UserSchema);
-    BlogPost = mongoose.model('BlogPost', BlogPost);
-    const user = db.collection('user');
-    const blogpost = db.collection('blogpost');
-
-    const mIds = [];
-    const dIds = [];
-
-    const bmIds = [];
-    const bdIds = [];
-
-    const data = {
-      name: 'name',
-      age: 0,
-      likes: ['dogs', 'cats', 'pizza'],
-      address: ' Nowhere-ville USA',
-    };
-
-    // insert all of the data here
-    let count = 4000;
-    for (let i = 0; i < 1000; i++) {
-      data.age = Math.floor(Math.random() * 50);
-      User.create(data, function (err, u) {
-        if (err) {
-          throw err;
-        }
-        mIds.push(u.id);
-        --count || next();
-      });
-      const nData = utils.clone(data);
-      user.insertOne(nData, function (err, res) {
-        if (err) {
-          throw err;
-        }
-        dIds.push(res.insertedIds);
-        --count || next();
-      });
-      BlogPost.create(blogData, function (err, bp) {
-        if (err) {
-          throw err;
-        }
-        bmIds.push(bp.id);
-        --count || next();
-      });
-
-      const bpData = utils.clone(blogData);
-      blogpost.insertOne(bpData, function (err, res) {
-        if (err) {
-          throw err;
-        }
-        bdIds.push(res.insertedId);
-        --count || next();
-      });
-    }
-
-    let mi = 0,
-      di = 0,
-      bmi = 0,
-      bdi = 0;
-
-    function getNextmId() {
-      mi = ++mi % mIds.length;
-      return mIds[mi];
-    }
-
-    function getNextdId() {
-      di = ++di % dIds.length;
-      return dIds[di];
-    }
-
-    function getNextbmId() {
-      bmi = ++bmi % bmIds.length;
-      return bmIds[bmi];
-    }
-
-    function getNextbdId() {
-      bdi = ++bdi % bdIds.length;
-      return bdIds[bdi];
-    }
-
-    function closeDB() {
-      mongoose.connection.db.dropDatabase(function () {
-        mongoose.disconnect();
-        process.exit();
-      });
-    }
-
-    suite
-      .add('Multi-Op - Mongoose - Heavy Read, low write', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-          for (let i = 0; i < 150; i++) {
-            User.findOne({ _id: getNextmId() }, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              const nData = utils.clone(data);
-              User.create(nData, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Driver - Heavy Read, low write', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-          for (let i = 0; i < 150; i++) {
-            user.findOne({ _id: getNextdId() }, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              const nData = utils.clone(data);
-              user.insertOne(nData, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Mongoose - Embedded Docs - Heavy Read, low write', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-          for (let i = 0; i < 150; i++) {
-            BlogPost.findOne({ _id: getNextbmId() }, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              const nData = utils.clone(blogData);
-              BlogPost.create(nData, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Driver - Embedded Docs - Heavy Read, low write', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-          for (let i = 0; i < 150; i++) {
-            blogpost.findOne({ _id: getNextbdId() }, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              const nData = utils.clone(blogData);
-              blogpost.insertOne(nData, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Mongoose - Heavy Write, low read', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-
-          for (let i = 0; i < 150; i++) {
-            const nData = utils.clone(data);
-            User.create(nData, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              User.findOne({ _id: getNextmId() }, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Driver - Heavy Write, low read', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-
-          for (let i = 0; i < 150; i++) {
-            const nData = utils.clone(data);
-            user.insertOne(nData, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              user.findOne({ _id: getNextdId() }, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Mongoose - Embedded Docs - Heavy Write, low read', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-
-          for (let i = 0; i < 150; i++) {
-            const nData = utils.clone(blogData);
-            BlogPost.create(nData, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              BlogPost.findOne({ _id: getNextbmId() }, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Driver - Embedded Docs - Heavy Write, low read', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-
-          for (let i = 0; i < 150; i++) {
-            const nData = utils.clone(blogData);
-            blogpost.insertOne(nData, function (err) {
-              if (err) {
-                throw err;
-              }
-              --count || deferred.resolve();
-            });
-            if (i % 15 === 0) {
-              blogpost.findOne({ _id: getNextbdId() }, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Mongoose - Embedded Docs - Read-write-update', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-          let updates = 0;
-          for (let i = 0; i < 150; i++) {
-            BlogPost.findOne({ _id: getNextbmId() }, function (err, res) {
-              if (err) {
-                throw err;
-              }
-              if (updates < 20) {
-                updates++;
-                res.author = 'soemthing new';
-                res.comments.push(commentData);
-                res.title = 'something newerrrr';
-                res.save(function (err) {
-                  if (err) {
-                    throw err;
-                  }
-                  --count || deferred.resolve();
-                });
-              } else {
-                --count || deferred.resolve();
-              }
-            });
-            if (i % 15 === 0) {
-              const nData = utils.clone(blogData);
-              BlogPost.create(nData, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .add('Multi-Op - Driver - Embedded Docs - Read-write-update', {
-        defer: true,
-        fn: function (deferred) {
-          let count = 150;
-          let updates = 0;
-          for (let i = 0; i < 150; i++) {
-            blogpost.findOne({ _id: getNextbdId() }, function (err, bp) {
-              if (err) {
-                throw err;
-              }
-              if (updates < 20) {
-                updates++;
-                blogpost.updateOne(
-                  { _id: bp._id },
-                  {
-                    $set: {
-                      author: 'something new',
-                      title: 'something newerrrr',
-                    },
-                    $push: {
-                      comments: commentData,
-                    },
-                  },
-                  { upsert: true },
-                  function (err) {
-                    if (err) {
-                      throw err;
-                    }
-                    --count || deferred.resolve();
-                  }
-                );
-              } else {
-                --count || deferred.resolve();
-              }
-            });
-            if (i % 15 === 0) {
-              const nData = utils.clone(blogData);
-              blogpost.insertOne(nData, function (err) {
-                if (err) {
-                  throw err;
-                }
-                --count || deferred.resolve();
-              });
-            }
-          }
-        },
-      })
-      .on('cycle', function (evt) {
-        if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-          console.log(String(evt.target));
-        }
-      })
-      .on('complete', function () {
-        closeDB();
-        if (!process.env.MONGOOSE_DEV && !process.env.PULL_REQUEST) {
-          const outObj = {};
-          this.forEach(function (item) {
-            const out = {};
-            out.stats = item.stats;
-            delete out.stats.sample;
-            out.ops = item.hz;
-            outObj[item.name.replace(/\s/g, '')] = out;
-          });
-          console.dir(outObj, { depth: null, colors: true });
-        }
-      });
-    function next() {
-      suite.run({ async: true });
-    }
-  });
-});
diff --git a/benchmarks/benchjs/population.js b/benchmarks/benchjs/population.js
deleted file mode 100644
index dc55ac1cae..0000000000
--- a/benchmarks/benchjs/population.js
+++ /dev/null
@@ -1,410 +0,0 @@
-'use strict';
-const mongoose = require('../../lib');
-const Benchmark = require('benchmark');
-
-const suite = new Benchmark.Suite();
-
-const Schema = mongoose.Schema;
-const ObjectId = Schema.Types.ObjectId;
-const utils = require('../../lib/utils.js');
-
-// to make things work in the way the are normally described online...
-/*
- *global.Schema = Schema;
- *global.mongoose = mongoose;
- */
-
-/**
- * These are all the benchmark tests for population ops
- */
-
-mongoose.connect('mongodb://127.0.0.1/mongoose-bench', function (err) {
-  if (err) {
-    throw err;
-  }
-
-  const commentSchema = new Schema();
-  commentSchema.add({
-    title: String,
-    date: Date,
-    body: String,
-  });
-  const dummy1Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy2Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy3Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy4Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy5Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy6Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy7Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy8Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-  const dummy9Schema = new Schema({
-    title: String,
-    isThisTest: Boolean,
-  });
-
-  let BlogPost = new Schema({
-    title: String,
-    author: String,
-    slug: String,
-    date: Date,
-    meta: {
-      date: Date,
-      visitors: Number,
-    },
-    published: Boolean,
-    mixed: {},
-    numbers: [Number],
-    tags: [String],
-    owners: [ObjectId],
-    comments: [{ type: ObjectId, ref: 'Comment' }],
-    dummy1: [{ type: ObjectId, ref: 'Dummy1' }],
-    dummy2: [{ type: ObjectId, ref: 'Dummy2' }],
-    dummy3: [{ type: ObjectId, ref: 'Dummy3' }],
-    dummy4: [{ type: ObjectId, ref: 'Dummy4' }],
-    dummy5: [{ type: ObjectId, ref: 'Dummy5' }],
-    dummy6: [{ type: ObjectId, ref: 'Dummy6' }],
-    dummy7: [{ type: ObjectId, ref: 'Dummy7' }],
-    dummy8: [{ type: ObjectId, ref: 'Dummy8' }],
-    dummy9: [{ type: ObjectId, ref: 'Dummy9' }],
-    def: { type: String, default: 'kandinsky' },
-  });
-
-  const blogData = {
-    title: 'dummy post',
-    author: 'somebody',
-    slug: 'test.post',
-    date: new Date(),
-    meta: { date: new Date(), visitors: 9001 },
-    published: true,
-    mixed: { thisIsRandom: true },
-    numbers: [1, 2, 7, 10, 23432],
-    tags: ['test', 'BENCH', 'things', 'more things'],
-    def: 'THANGS!!!',
-    comments: [],
-    dummy1: [],
-    dummy2: [],
-    dummy3: [],
-    dummy4: [],
-    dummy5: [],
-    dummy6: [],
-    dummy7: [],
-    dummy8: [],
-    dummy9: [],
-  };
-  const commentData = {
-    title: 'test comment',
-    date: new Date(),
-    body: 'this be some crazzzyyyyy text that would go in a comment',
-  };
-  const dummyData = {
-    title: 'dummy data~',
-    isThisTest: true,
-  };
-  const Comments = mongoose.model('Comment', commentSchema);
-  BlogPost = mongoose.model('BlogPost', BlogPost);
-  const Dummy1 = mongoose.model('Dummy1', dummy1Schema);
-  const Dummy2 = mongoose.model('Dummy2', dummy2Schema);
-  const Dummy3 = mongoose.model('Dummy3', dummy3Schema);
-  const Dummy4 = mongoose.model('Dummy4', dummy4Schema);
-  const Dummy5 = mongoose.model('Dummy5', dummy5Schema);
-  const Dummy6 = mongoose.model('Dummy6', dummy6Schema);
-  const Dummy7 = mongoose.model('Dummy7', dummy7Schema);
-  const Dummy8 = mongoose.model('Dummy8', dummy8Schema);
-  const Dummy9 = mongoose.model('Dummy9', dummy9Schema);
-  const cIds = [];
-  const dIds = [];
-  for (let i = 0; i < 9; i++) {
-    dIds.push([]);
-  }
-
-  let cn = 5000;
-  for (let i = 0; i < 500; i++) {
-    Comments.create(commentData, function (err, com) {
-      cIds.push(com.id);
-      --cn || cont();
-    });
-    Dummy1.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[0].push(d.id);
-      --cn || cont();
-    });
-    Dummy2.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[1].push(d.id);
-      --cn || cont();
-    });
-    Dummy3.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[2].push(d.id);
-      --cn || cont();
-    });
-    Dummy4.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[3].push(d.id);
-      --cn || cont();
-    });
-    Dummy5.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[4].push(d.id);
-      --cn || cont();
-    });
-    Dummy6.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[5].push(d.id);
-      --cn || cont();
-    });
-    Dummy7.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[6].push(d.id);
-      --cn || cont();
-    });
-    Dummy8.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[7].push(d.id);
-      --cn || cont();
-    });
-    Dummy9.create(dummyData, function (err, d) {
-      if (err) {
-        throw err;
-      }
-      dIds[8].push(d.id);
-      --cn || cont();
-    });
-  }
-
-  const blog = [];
-
-  function cont() {
-    blog[0] = utils.clone(blogData);
-    blog[1] = utils.clone(blogData);
-    blog[2] = utils.clone(blogData);
-    blog[3] = utils.clone(blogData);
-    blogData.comments.push(getNextcId());
-    blog[4] = blogData;
-
-    blog[5] = utils.clone(blogData);
-    blog[6] = utils.clone(blogData);
-
-    for (let i = 0; i < 10; i++) {
-      blog[0].comments.push(getNextcId());
-    }
-    for (let i = 0; i < 100; i++) {
-      blog[1].comments.push(getNextcId());
-    }
-    for (let i = 0; i < 1000; i++) {
-      blog[2].comments.push(getNextcId());
-    }
-    for (let i = 0; i < 10000; i++) {
-      blog[3].comments.push(getNextcId());
-    }
-    for (let i = 0; i < 100; i++) {
-      blog[5].comments.push(getNextcId());
-      blog[6].comments.push(getNextcId());
-
-      blog[5].dummy1.push(getNextdId(0));
-      blog[5].dummy2.push(getNextdId(1));
-      blog[5].dummy3.push(getNextdId(2));
-      blog[5].dummy4.push(getNextdId(3));
-
-      blog[6].dummy1.push(getNextdId(0));
-      blog[6].dummy2.push(getNextdId(1));
-      blog[6].dummy3.push(getNextdId(2));
-      blog[6].dummy4.push(getNextdId(3));
-      blog[6].dummy5.push(getNextdId(4));
-      blog[6].dummy1.push(getNextdId(5));
-      blog[6].dummy2.push(getNextdId(6));
-      blog[6].dummy3.push(getNextdId(7));
-      blog[6].dummy4.push(getNextdId(8));
-    }
-
-    let count = 7;
-
-    function iter(c) {
-      BlogPost.create(blog[c], function (err, bl) {
-        if (err) {
-          throw err;
-        }
-        blog[c] = bl;
-        --count || next();
-      });
-    }
-
-    // insert all of the data here
-    for (let i = 0; i < blog.length; i++) {
-      // use some closure magic to make sure we retain the index
-      iter(i);
-    }
-  }
-
-  let ci = 0;
-  const di = [];
-  for (let i = 0; i < 9; i++) {
-    di.push(0);
-  }
-
-  function getNextcId() {
-    ci = ++ci % cIds.length;
-    return cIds[ci];
-  }
-
-  function getNextdId(i) {
-    di[i] = ++di[i] % dIds[i].length;
-    return dIds[i][di[i]];
-  }
-
-  function closeDB() {
-    // just a bit simpler...
-    mongoose.connection.db.dropDatabase(function () {
-      mongoose.disconnect();
-      process.exit();
-    });
-  }
-
-  suite
-    .add('Populate - 1 value', {
-      defer: true,
-      fn: function (deferred) {
-        blog[4].populate('comments', function (err) {
-          if (err) {
-            throw err;
-          }
-          deferred.resolve();
-        });
-      },
-    })
-    .add('Populate - 10 values', {
-      defer: true,
-      fn: function (deferred) {
-        blog[0].populate('comments', function (err) {
-          if (err) {
-            throw err;
-          }
-          deferred.resolve();
-        });
-      },
-    })
-    .add('Populate - 100 values', {
-      defer: true,
-      fn: function (deferred) {
-        blog[1].populate('comments', function (err) {
-          if (err) {
-            throw err;
-          }
-          deferred.resolve();
-        });
-      },
-    })
-    .add('Populate - 1000 values', {
-      defer: true,
-      fn: function (deferred) {
-        blog[2].populate('comments', function (err) {
-          if (err) {
-            throw err;
-          }
-          deferred.resolve();
-        });
-      },
-    })
-    .add('Populate - 10000 values', {
-      defer: true,
-      fn: function (deferred) {
-        blog[3].populate('comments', function (err) {
-          if (err) {
-            throw err;
-          }
-          deferred.resolve();
-        });
-      },
-    })
-    .add('Populate - 5 properties', {
-      defer: true,
-      fn: function (deferred) {
-        blog[5].populate(
-          'comments dummy1 dummy2 dummy3 dummy4',
-          function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          }
-        );
-      },
-    })
-    .add('Populate - 10 properties', {
-      defer: true,
-      fn: function (deferred) {
-        blog[6].populate(
-          'comments dummy1 dummy2 dummy3 dummy4 dummy5 dummy6 dummy7 dummy8 dummy9',
-          function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          }
-        );
-      },
-    })
-
-    .on('cycle', function (evt) {
-      if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-        console.log(String(evt.target));
-      }
-    })
-    .on('complete', function () {
-      closeDB();
-      if (!process.env.MONGOOSE_DEV && !process.env.PULL_REQUEST) {
-        const outObj = {};
-        this.forEach(function (item) {
-          const out = {};
-          out.stats = item.stats;
-          delete out.stats.sample;
-          out.ops = item.hz;
-          outObj[item.name.replace(/\s/g, '')] = out;
-        });
-        console.dir(outObj, { depth: null, colors: true });
-      }
-    });
-  function next() {
-    suite.run({ async: true });
-  }
-});
diff --git a/benchmarks/benchjs/read.js b/benchmarks/benchjs/read.js
deleted file mode 100644
index 35d39b9091..0000000000
--- a/benchmarks/benchjs/read.js
+++ /dev/null
@@ -1,319 +0,0 @@
-'use strict';
-
-const mongoose = require('../../lib');
-const Benchmark = require('benchmark');
-
-const suite = new Benchmark.Suite();
-
-const Schema = mongoose.Schema;
-const ObjectId = Schema.Types.ObjectId;
-const mongoClient = require('mongodb').MongoClient;
-const utils = require('../../lib/utils.js');
-
-// to make things work in the way the are normally described online...
-/*
- *global.Schema = Schema;
- *global.mongoose = mongoose;
- */
-
-/**
- * These are all the benchmark tests for reading data
- */
-
-mongoose.connect('mongodb://127.0.0.1/mongoose-bench', function (err) {
-  if (err) {
-    throw err;
-  }
-  mongoClient.connect('mongodb://127.0.0.1', function (err, client) {
-    if (err) {
-      throw err;
-    }
-
-    const db = client.db('mongoose-bench');
-
-    const Comments = new Schema();
-    Comments.add({
-      title: String,
-      date: Date,
-      body: String,
-      comments: [Comments],
-    });
-
-    let BlogPost = new Schema({
-      title: String,
-      author: String,
-      slug: String,
-      date: Date,
-      meta: {
-        date: Date,
-        visitors: Number,
-      },
-      published: Boolean,
-      mixed: {},
-      numbers: [Number],
-      tags: [String],
-      owners: [ObjectId],
-      comments: [Comments],
-      def: {
-        type: String,
-        default: 'kandinsky',
-      },
-    });
-
-    const blogData = {
-      title: 'dummy post',
-      author: 'somebody',
-      slug: 'test.post',
-      date: new Date(),
-      meta: { date: new Date(), visitors: 9001 },
-      published: true,
-      mixed: { thisIsRandom: true },
-      numbers: [1, 2, 7, 10, 23432],
-      tags: ['test', 'BENCH', 'things', 'more things'],
-      def: 'THANGS!!!',
-      comments: [],
-    };
-    const commentData = {
-      title: 'test comment',
-      date: new Date(),
-      body: 'this be some crazzzyyyyy text that would go in a comment',
-      comments: [{ title: 'second level', date: new Date(), body: 'texttt' }],
-    };
-    for (let i = 0; i < 5; i++) {
-      blogData.comments.push(commentData);
-    }
-    const UserSchema = new Schema({
-      name: String,
-      age: Number,
-      likes: [String],
-      address: String,
-    });
-
-    const User = mongoose.model('User', UserSchema);
-    BlogPost = mongoose.model('BlogPost', BlogPost);
-    const user = db.collection('user');
-    const blogpost = db.collection('blogpost');
-
-    const mIds = [];
-    const dIds = [];
-
-    const bmIds = [];
-    const bdIds = [];
-
-    const data = {
-      name: 'name',
-      age: 0,
-      likes: ['dogs', 'cats', 'pizza'],
-      address: ' Nowhere-ville USA',
-    };
-
-    // insert all of the data here
-    let count = 4000;
-    for (let i = 0; i < 1000; i++) {
-      data.age = Math.floor(Math.random() * 50);
-      User.create(data, function (err, u) {
-        if (err) {
-          throw err;
-        }
-        mIds.push(u.id);
-        --count || next();
-      });
-      const nData = utils.clone(data);
-      user.insertOne(nData, function (err, res) {
-        if (err) {
-          throw err;
-        }
-        dIds.push(res.insertedId);
-        --count || next();
-      });
-      BlogPost.create(blogData, function (err, bp) {
-        if (err) {
-          throw err;
-        }
-        bmIds.push(bp.id);
-        --count || next();
-      });
-
-      const bpData = utils.clone(blogData);
-      blogpost.insertOne(bpData, function (err, res) {
-        if (err) {
-          throw err;
-        }
-        bdIds.push(res.insertedId);
-        --count || next();
-      });
-    }
-
-    let mi = 0,
-      di = 0,
-      bmi = 0,
-      bdi = 0;
-
-    function getNextmId() {
-      mi = ++mi % mIds.length;
-      return mIds[mi];
-    }
-
-    function getNextdId() {
-      di = ++di % dIds.length;
-      return dIds[di];
-    }
-
-    function getNextbmId() {
-      bmi = ++bmi % bmIds.length;
-      return bmIds[bmi];
-    }
-
-    function getNextbdId() {
-      bdi = ++bdi % bdIds.length;
-      return bdIds[bdi];
-    }
-
-    function closeDB() {
-      mongoose.connection.db.dropDatabase(function () {
-        mongoose.disconnect();
-        process.exit();
-      });
-    }
-
-    suite
-      .add('Read - Mongoose - Basic', {
-        defer: true,
-        fn: function (deferred) {
-          User.findOne({ _id: getNextmId() }, function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Read - Driver - Basic', {
-        defer: true,
-        fn: function (deferred) {
-          user.findOne({ _id: getNextdId() }, function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Read - Mongoose - With lean', {
-        defer: true,
-        fn: function (deferred) {
-          User.findOne(
-            { _id: getNextmId() },
-            {},
-            { lean: true },
-            function (err) {
-              if (err) {
-                throw err;
-              }
-              deferred.resolve();
-            }
-          );
-        },
-      })
-      .add('Read - Mongoose - Multiple Items', {
-        defer: true,
-        fn: function (deferred) {
-          const ids = [];
-          for (let i = 0; i < 25; i++) {
-            ids.push(getNextmId());
-          }
-          User.find({ _id: { $in: ids } }, function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Read - Driver - Multiple Items', {
-        defer: true,
-        fn: function (deferred) {
-          const ids = [];
-          for (let i = 0; i < 25; i++) {
-            ids.push(getNextdId());
-          }
-          user.find({ _id: { $in: ids } }).toArray(function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Read - Mongoose - Non-index', {
-        defer: true,
-        fn: function (deferred) {
-          const age = Math.floor(Math.random() * 50);
-
-          User.find({ age: age }, function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Read - Driver - Non-index', {
-        defer: true,
-        fn: function (deferred) {
-          const age = Math.floor(Math.random() * 50);
-
-          user.find({ age: age }).toArray(function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Read - Mongoose - Embedded Docs', {
-        defer: true,
-        fn: function (deferred) {
-          BlogPost.find({ _id: getNextbmId() }, function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .add('Read - Driver - Embedded Docs', {
-        defer: true,
-        fn: function (deferred) {
-          blogpost.find({ _id: getNextbdId() }).toArray(function (err) {
-            if (err) {
-              throw err;
-            }
-            deferred.resolve();
-          });
-        },
-      })
-      .on('cycle', function (evt) {
-        if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-          console.log(String(evt.target));
-        }
-      })
-      .on('complete', function () {
-        closeDB();
-        if (!process.env.MONGOOSE_DEV && !process.env.PULL_REQUEST) {
-          const outObj = {};
-          this.forEach(function (item) {
-            const out = {};
-            out.stats = item.stats;
-            delete out.stats.sample;
-            out.ops = item.hz;
-            outObj[item.name.replace(/\s/g, '')] = out;
-          });
-          console.dir(outObj, { depth: null, colors: true });
-        }
-      });
-    function next() {
-      suite.run({ async: true });
-    }
-  });
-});
diff --git a/benchmarks/bigboard.json b/benchmarks/bigboard.json
deleted file mode 100644
index 0c22211c9f..0000000000
--- a/benchmarks/bigboard.json
+++ /dev/null
@@ -1,1909 +0,0 @@
-{
-    "_id": "4d5ea62fd76aa1136000000c",
-    "checklists": [{
-        "_id": "4daee890aae47fe55305dd72",
-        "checkItems": [{
-            "_id": "4daee8a2aae47fe55305eabf",
-            "pos": 32768,
-            "type": "check",
-            "name": "delete checklists"
-        }, {
-            "_id": "4daee8a6aae47fe55305eb4e",
-            "pos": 49152,
-            "type": "check",
-            "name": "delete checklist items"
-        }, {
-            "_id": "4daeec4caae47fe5530730be",
-            "pos": 65536,
-            "type": "check",
-            "name": "Link to card on action in activity feed"
-        }, {
-            "_id": "4daeeca6aae47fe5530748b8",
-            "pos": 81920,
-            "type": "check",
-            "name": "Edit controls on new task input"
-        }, {
-            "_id": "4daeeda4aae47fe553080e92",
-            "pos": 98304,
-            "type": "check",
-            "name": "Actions for checklist item add, change, delete, reorder, etc."
-        }, {
-            "_id": "4db06f77c9fd63357d0a44ed",
-            "pos": 114688,
-            "type": "check",
-            "name": "Click 'Add checklist' -> focus on new task, let title be 'Checklist', but editable"
-        }],
-        "name": "Features"
-    }, {
-        "checkItems": [{
-            "_id": "4db09065c9fd63357d118d0f",
-            "pos": 0,
-            "type": "check",
-            "name": "Make it obvious that you can't do stuff to the board"
-        }, {
-            "_id": "4db0906fc9fd63357d118d75",
-            "pos": 16384,
-            "type": "check",
-            "name": "/#browse/"
-        }, {
-            "_id": "4db0908ac9fd63357d118e54",
-            "pos": 32768,
-            "type": "check",
-            "name": "Cut you off from further updates when you can't see the board any more"
-        }],
-        "_id": "4db09054c9fd63357d117284",
-        "name": "Remaining"
-    }, {
-        "checkItems": [{
-            "_id": "4db5b8a9697ba7cc023bc737",
-            "pos": 0,
-            "type": "check",
-            "name": "You can check things off of a checklist [brett]"
-        }, {
-            "_id": "4db5b8bf697ba7cc023bc874",
-            "pos": 16384,
-            "type": "check",
-            "name": "Moving lists [brett]"
-        }, {
-            "_id": "4db5b8fa697ba7cc023be27f",
-            "pos": 32768,
-            "type": "check",
-            "name": "Assign members by dragging"
-        }, {
-            "_id": "4db5b8fc697ba7cc023be2bb",
-            "pos": 49152,
-            "type": "check",
-            "name": "Removing members from cards via avatar pop over menu"
-        }, {
-            "_id": "4db5b909697ba7cc023be3b7",
-            "pos": 65536,
-            "type": "check",
-            "name": "Remove members from board via sidebar"
-        }, {
-            "_id": "4db5b90e697ba7cc023be406",
-            "pos": 81920,
-            "type": "check",
-            "name": "Close lists via list menu"
-        }, {
-            "_id": "4db5bae6697ba7cc023dea6a",
-            "pos": 98304,
-            "type": "check",
-            "name": "Do everything via board menu"
-        }, {
-            "_id": "4db5cef7697ba7cc023f97f4",
-            "pos": 114688,
-            "type": "check",
-            "name": "we lost list reopen"
-        }],
-        "_id": "4db43519697ba7cc0227e6d7",
-        "name": "Places where it still looks like you can edit"
-    }, {
-        "checkItems": [{
-            "_id": "4db747935413f9d20c0b5eaa",
-            "pos": 0,
-            "type": "check",
-            "name": "Finish checklists v2"
-        }, {
-            "_id": "4db7479b5413f9d20c0b5eeb",
-            "pos": 16384,
-            "type": "check",
-            "name": "Delete this checklist"
-        }],
-        "_id": "4db745f75413f9d20c0adb0d",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4db8384582ab23241000c157",
-            "pos": 0,
-            "type": "check",
-            "name": "Links in comments causing dialog window width problems"
-        }, {
-            "_id": "4db8386782ab23241000cb40",
-            "pos": 16384,
-            "type": "check",
-            "name": "'card operations' (grey dude, close) showing up on click"
-        }, {
-            "_id": "4db8388882ab23241000d0ab",
-            "pos": 32768,
-            "type": "check",
-            "name": "scrolltop not being set correctly"
-        }],
-        "_id": "4db8383582ab232410009fc4",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4db852b24b06719a1005014c",
-            "pos": 0,
-            "type": "check",
-            "name": "Cursor is pointer for list and board titles on public board"
-        }, {
-            "_id": "4db861334b06719a10076026",
-            "pos": 16384,
-            "type": "check",
-            "name": "Looks like I can add checklist items to cards that already hace checklists"
-        }, {
-            "_id": "4db8615f4b06719a10077a73",
-            "pos": 32768,
-            "type": "check",
-            "name": "Looks like I can edit checklist titles"
-        }],
-        "_id": "4db852a54b06719a1004f9b9",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dbafb7c6cc6af2018042d9d",
-            "pos": 16384,
-            "type": "check",
-            "name": "Link 'Boards' to member/boards from the member page"
-        }, {
-            "_id": "4dbafb836cc6af2018042e0c",
-            "pos": 32768,
-            "type": "check",
-            "name": "Link to 'Boards' from the menu"
-        }, {
-            "_id": "4dbafb8f6cc6af2018042ee8",
-            "pos": 49152,
-            "type": "check",
-            "name": "Remove the boards from the member detail page"
-        }, {
-            "_id": "4dbafbad6cc6af2018045d3c",
-            "pos": 65536,
-            "type": "check",
-            "name": "Make server-side data provider data/board/list/mine/updates"
-        }, {
-            "_id": "4dbafc706cc6af2018049bd2",
-            "pos": 98304,
-            "type": "check",
-            "name": "BoardStatsListView"
-        }, {
-            "_id": "4dbafc766cc6af2018049c3f",
-            "pos": 114688,
-            "type": "check",
-            "name": "MemberBoardsView"
-        }, {
-            "_id": "4dbee92360f4e2b21d01a2ed",
-            "pos": 131072,
-            "type": "check",
-            "name": "Merge views and templates for profile and board pages"
-        }],
-        "_id": "4dbafb686cc6af20180422b0",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dc7e84ee92755263100e7d1",
-            "pos": 16384,
-            "type": "check",
-            "name": "actions.js [brett]"
-        }, {
-            "_id": "4dc7e858e92755263100e87b",
-            "pos": 32768,
-            "type": "check",
-            "name": "notifications.js [brett]"
-        }],
-        "_id": "4dc7e841e92755263100e045",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dc7e8dfe927552631012742",
-            "pos": 16384,
-            "type": "check",
-            "name": "Patch controller"
-        }, {
-            "_id": "4dc7e8ece9275526310127f7",
-            "pos": 32768,
-            "type": "check",
-            "name": "Server side support for member URLs"
-        }, {
-            "_id": "4dc7e8f6e92755263101290f",
-            "pos": 49152,
-            "type": "check",
-            "name": "Server side support for board URLs"
-        }, {
-            "_id": "4dc9379612f8cee93501af53",
-            "pos": 65536,
-            "type": "check",
-            "name": "Backwards compatible hash version"
-        }, {
-            "_id": "4dc937bb12f8cee93501b18b",
-            "pos": 98304,
-            "type": "check",
-            "name": "quickload for members"
-        }, {
-            "_id": "4dc93f5b12f8cee9350270af",
-            "pos": 114688,
-            "type": "check",
-            "name": "backfill username"
-        }, {
-            "_id": "4dc951466a4b5c603601f461",
-            "pos": 131072,
-            "type": "check",
-            "name": "enforce username select on account create"
-        }, {
-            "_id": "4dc9929ee236cc1e370c0cd3",
-            "pos": 147456,
-            "type": "check",
-            "name": "card URLs"
-        }],
-        "_id": "4dc7e8cde927552631011f32",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dc849a6ba75abdf3205d35a",
-            "pos": 16384,
-            "type": "check",
-            "name": "Verify use of tokens in ajaxRpc"
-        }],
-        "_id": "4dc84984ba75abdf3205c95e",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dcaa2125c09b74e3e03bbf7",
-            "pos": 16384,
-            "type": "check",
-            "name": "Give another user co-ownership of a board"
-        }, {
-            "_id": "4dcaa2295c09b74e3e03bd96",
-            "pos": 32768,
-            "type": "check",
-            "name": "Remove your own ownership if there is a remaining owner"
-        }],
-        "_id": "4dcaa2085c09b74e3e03b00f",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dcc42565dcb84024615584d",
-            "pos": 16384,
-            "type": "check",
-            "name": "schema"
-        }, {
-            "_id": "4dcc425b5dcb8402461558e8",
-            "pos": 32768,
-            "type": "check",
-            "name": "action wiring"
-        }, {
-            "_id": "4dcc42695dcb840246155a72",
-            "pos": 65536,
-            "type": "check",
-            "name": "immediate vote feedback"
-        }, {
-            "_id": "4dcc42875dcb840246156d68",
-            "pos": 81920,
-            "type": "check",
-            "name": "action display"
-        }, {
-            "_id": "4dcd3c585dcb840246221dee",
-            "pos": 98304,
-            "type": "check",
-            "name": "badges"
-        }],
-        "_id": "4dcc41e25dcb84024614df30",
-        "name": "Checklist"
-    }, {
-        "_id": "4dcd6da85dcb84024629626c",
-        "checkItems": [{
-            "_id": "4dcd6dd45dcb8402462973a1",
-            "pos": 49152,
-            "type": "check",
-            "name": "Readable URLs"
-        }, {
-            "_id": "4dcd6de25dcb84024629750d",
-            "pos": 65536,
-            "type": "check",
-            "name": "PushState instead of /#"
-        }, {
-            "_id": "4dcd6df95dcb8402462976db",
-            "pos": 81920,
-            "type": "check",
-            "name": "Semantic Markup (good use of p tags, link text, img alt attributes)"
-        }, {
-            "_id": "4dcd6dfc5dcb840246297783",
-            "pos": 98304,
-            "type": "check",
-            "name": "Meta description"
-        }, {
-            "_id": "4dcd6e005dcb84024629783c",
-            "pos": 114688,
-            "type": "check",
-            "name": "Descriptive Page Titles"
-        }],
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dcd77c05dcb8402462d836d",
-            "pos": 16384,
-            "type": "check",
-            "name": "Skinny badge"
-        }, {
-            "_id": "4dcd77c95dcb8402462d845d",
-            "pos": 32768,
-            "type": "check",
-            "name": "Vote button state"
-        }],
-        "_id": "4dcd77a75dcb8402462d69ee",
-        "name": "Design Touch Ups"
-    }, {
-        "checkItems": [{
-            "_id": "4dcd96575dcb84024634b11e",
-            "pos": 16384,
-            "type": "check",
-            "name": "Propagate new commenting members (the member, not the idMembersRemoved) as soon as they comment"
-        }, {
-            "_id": "4dcd96655dcb84024634b29a",
-            "pos": 32768,
-            "type": "check",
-            "name": "Vote actions not showing up on cards"
-        }],
-        "_id": "4dcd96405dcb84024634a0f8",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dd11ecd5dcb840246509361",
-            "pos": 16384,
-            "type": "check",
-            "name": "delete attachments"
-        }, {
-            "_id": "4dd11ee45dcb84024650d68a",
-            "pos": 32768,
-            "type": "check",
-            "name": "badge for attachments"
-        }, {
-            "_id": "4dd122bf5dcb84024651be40",
-            "pos": 49152,
-            "type": "check",
-            "name": "icon for attachments badge"
-        }, {
-            "_id": "4dd1239b5dcb8402465202a6",
-            "pos": 65536,
-            "type": "check",
-            "name": "view attachments inside trellis?"
-        }, {
-            "_id": "4dd12d995dcb840246560562",
-            "pos": 81920,
-            "type": "check",
-            "name": "attach multiple files at once"
-        }, {
-            "_id": "4dd137315dcb84024659ea3c",
-            "pos": 98304,
-            "type": "check",
-            "name": "instant update of board action list when attachment is added"
-        }],
-        "_id": "4dd11ec95dcb840246508972",
-        "name": "Checklist"
-    }, {
-        "checkItems": [{
-            "_id": "4dd138a85dcb8402465aad37",
-            "pos": 16384,
-            "type": "check",
-            "name": "IE 9 choke on console.log"
-        }, {
-            "_id": "4dd138e65dcb8402465ad86d",
-            "pos": 32768,
-            "type": "check",
-            "name": "Can add a due date from a public comment [brett]"
-        }, {
-            "_id": "4dd139025dcb8402465b4c99",
-            "pos": 49152,
-            "type": "check",
-            "name": "public viewers can see \"add checklist item\""
-        }, {
-            "_id": "4dd1391a5dcb8402465b4eac",
-            "pos": 65536,
-            "type": "check",
-            "name": "public viewers get JS error when trying to open member menu"
-        }, {
-            "_id": "4dd13d5e5dcb8402465efad0",
-            "pos": 81920,
-            "type": "check",
-            "name": "don't use cursor:pointer on checklist items for public viewers"
-        }, {
-            "_id": "4dd144e35dcb840246630e4e",
-            "pos": 98304,
-            "type": "check",
-            "name": "color vote badge when it includes a vote from you [daniel]"
-        }, {
-            "_id": "4dd146dd5dcb8402466410ae",
-            "pos": 114688,
-            "type": "check",
-            "name": "Adding an attachment doesn't instantly give a card an attachment badge [brett]"
-        }],
-        "_id": "4dd1389c5dcb8402465a7bc9",
-        "name": "Checklist"
-    }, {
-        "_id": "4dd139ce5dcb8402465bcbf9",
-        "checkItems": [{
-            "_id": "4dd139dd5dcb8402465c3cd5",
-            "pos": 32768,
-            "type": "check",
-            "name": "Can't quick enter checklist items on all browsers"
-        }, {
-            "_id": "4dd139ed5dcb8402465c65e8",
-            "pos": 49152,
-            "type": "check",
-            "name": "hide attachments upload button from iOS devices"
-        }, {
-            "_id": "4dd13a3c5dcb8402465d3cdc",
-            "pos": 65536,
-            "type": "check",
-            "name": "Button active state \"sticks\" on iOS"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dd163620bd1b83a5b0e7c00",
-        "checkItems": [{
-            "_id": "4dd1638b0bd1b83a5b0e8abe",
-            "name": "Labels button and pop-over in card detail [bobby]",
-            "pos": 32768,
-            "type": "check"
-        }, {
-            "_id": "4dd163b10bd1b83a5b0e991f",
-            "name": "Palette [bobby]",
-            "pos": 49152,
-            "type": "check"
-        }, {
-            "_id": "4dd28be8728b921a5d1fbb42",
-            "pos": 65536,
-            "type": "check",
-            "name": "HTML/CSS"
-        }],
-        "name": "Design Checklist"
-    }, {
-        "_id": "4dd177f40bd1b83a5b1c57a9",
-        "checkItems": [{
-            "_id": "4dd178390bd1b83a5b1c6760",
-            "pos": 16384,
-            "type": "check",
-            "name": "Spawn multiple processes: Cluster?"
-        }, {
-            "_id": "4dd178d60bd1b83a5b1cc066",
-            "name": "PubSub: Redis",
-            "pos": 32768,
-            "type": "check"
-        }, {
-            "_id": "4dd69b0d7165bb5c7243f933",
-            "name": "Heartbeat / Sessions",
-            "pos": 49152,
-            "type": "check"
-        }, {
-            "_id": "4dda546b19e692e0053d9be5",
-            "pos": 65536,
-            "type": "check",
-            "name": "Go to a single minify step across all processes (maybe on release)"
-        }, {
-            "_id": "4ddac01e566cceb30f14e1c2",
-            "pos": 81920,
-            "type": "check",
-            "name": "Redis on trellisny1"
-        }, {
-            "_id": "4ddd1ef993234c0814377408",
-            "pos": 114688,
-            "type": "check",
-            "name": "ajax RPC consistency"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dd28ae9728b921a5d1e1249",
-        "checkItems": [{
-            "_id": "4dd28af0728b921a5d1e2295",
-            "pos": 16384,
-            "type": "check",
-            "name": "Way to clear due date"
-        }, {
-            "_id": "4dd28afb728b921a5d1e246b",
-            "pos": 32768,
-            "type": "check",
-            "name": "Add due dates from card actions (pop over menu)"
-        }, {
-            "_id": "4dd28b15728b921a5d1e267a",
-            "pos": 49152,
-            "type": "check",
-            "name": "Fuzzy dates"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dd2da8d728b921a5d30c42b",
-        "checkItems": [{
-            "_id": "4dd2da93728b921a5d30d50e",
-            "pos": 16384,
-            "type": "check",
-            "name": "Get a real cert"
-        }, {
-            "_id": "4dd2dab1728b921a5d30d6e3",
-            "pos": 32768,
-            "type": "check",
-            "name": "Use an options parser instead of the current crazy long positional opts"
-        }, {
-            "_id": "4dd2dab6728b921a5d30d7d9",
-            "pos": 49152,
-            "type": "check",
-            "name": "Test like crazy"
-        }, {
-            "_id": "4dd2dac4728b921a5d30d8fb",
-            "pos": 65536,
-            "type": "check",
-            "name": "modify start.sh to use ssl"
-        }, {
-            "_id": "4dd2ddf6728b921a5d316f84",
-            "pos": 81920,
-            "type": "check",
-            "name": "node 0.4.7 running on trellisny1"
-        }, {
-            "_id": "4dd50b2bb9a905d36627f88b",
-            "pos": 98304,
-            "type": "check",
-            "name": "key needs to be readable by trellis user."
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dd44cdeb9a905d3661bc337",
-        "checkItems": [{
-            "_id": "4dd44ce3b9a905d3661bd52e",
-            "pos": 16384,
-            "type": "check",
-            "name": "public/private"
-        }, {
-            "_id": "4dd44ce5b9a905d3661bd620",
-            "pos": 32768,
-            "type": "check",
-            "name": "voting"
-        }, {
-            "_id": "4dd44ce7b9a905d3661bd714",
-            "pos": 49152,
-            "type": "check",
-            "name": "public comments"
-        }, {
-            "_id": "4dd44d01b9a905d3661bd9d8",
-            "pos": 81920,
-            "type": "check",
-            "name": "sidebar - members"
-        }, {
-            "_id": "4dd44d11b9a905d3661bdb11",
-            "pos": 98304,
-            "type": "check",
-            "name": "sidebar - board actions"
-        }, {
-            "_id": "4dd44d17b9a905d3661bdc8f",
-            "pos": 114688,
-            "type": "check",
-            "name": "sidebar - activity"
-        }, {
-            "_id": "4dd44d1bb9a905d3661bdd96",
-            "pos": 131072,
-            "type": "check",
-            "name": "list guide"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dd67bda7165bb5c723c2d49",
-        "checkItems": [{
-            "_id": "4dd67bf47165bb5c723c402c",
-            "pos": 16384,
-            "type": "check",
-            "name": "Fix flashsockets in the SSL case - they get flaky, esp. with multiple browser windows open"
-        }, {
-            "_id": "4dd67c207165bb5c723c42d9",
-            "pos": 32768,
-            "type": "check",
-            "name": "The flash policy server is turned off for multi-process trellis, because when every trellis tries to start it up there's a port conflict"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4ddeb510a9a2bd055c1337e0",
-        "checkItems": [{
-            "_id": "4ddeb525a9a2bd055c134a2e",
-            "pos": 16384,
-            "type": "check",
-            "name": "cards"
-        }, {
-            "_id": "4ddeb528a9a2bd055c134b56",
-            "pos": 32768,
-            "type": "check",
-            "name": "checklists"
-        }, {
-            "_id": "4ddeb529a9a2bd055c134c64",
-            "pos": 49152,
-            "type": "check",
-            "name": "lists"
-        }, {
-            "_id": "4ddeb52ba9a2bd055c134d82",
-            "pos": 65536,
-            "type": "check",
-            "name": "boards"
-        }, {
-            "_id": "4ddeb52da9a2bd055c134ea2",
-            "pos": 81920,
-            "type": "check",
-            "name": "members"
-        }, {
-            "_id": "4ddeb53ba9a2bd055c13501e",
-            "pos": 98304,
-            "type": "check",
-            "name": "board invites"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4ddeb83fa9a2bd055c14cfe5",
-        "checkItems": [{
-            "_id": "4ddeb853a9a2bd055c14e131",
-            "name": "Refactor sessions.js",
-            "pos": 16384,
-            "type": "check"
-        }, {
-            "_id": "4ddf9ce8478463e761026e64",
-            "pos": 49152,
-            "type": "check",
-            "name": "Fix notification race condition"
-        }, {
-            "_id": "4ddfa076478463e76103790e",
-            "name": "Get (correct) board watcher count back",
-            "pos": 65536,
-            "type": "check"
-        }, {
-            "_id": "4de289955c292e601a00d8a2",
-            "pos": 98304,
-            "type": "check",
-            "name": "node-openid stores associations per process - we need to fix that."
-        }, {
-            "_id": "4dffa580079f66be4b04396f",
-            "pos": 114688,
-            "type": "check",
-            "name": "over-publishing redis notifications"
-        }, {
-            "_id": "4e01e5214a2956844303cbc3",
-            "pos": 131072,
-            "type": "check",
-            "name": "/enabled.html to activate/deactivate server"
-        }, {
-            "_id": "4e0232408d64cbf783026e0a",
-            "pos": 147456,
-            "type": "check",
-            "name": "restore us to multiprocess, then to multiserver"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4ddfbbcf478463e7610a3621",
-        "checkItems": [{
-            "_id": "4ddfbbd7478463e7610a41bd",
-            "pos": 16384,
-            "type": "check",
-            "name": "schema.js: 790"
-        }, {
-            "_id": "4ddfbc40478463e7610a586e",
-            "pos": 32768,
-            "type": "check",
-            "name": "account.js: 108"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4de009d99669af6c6902b730",
-        "checkItems": [{
-            "_id": "4de009fb9669af6c6902bd81",
-            "pos": 16384,
-            "type": "check",
-            "name": "IE \"Socket not writable\" when trying to get ie.css on fresh browser login in IE9 in test"
-        }, {
-            "_id": "4de00a089669af6c6902bf49",
-            "pos": 32768,
-            "type": "check",
-            "name": "IE login laps in production"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4de3f6ae5c292e601a12e70f",
-        "checkItems": [{
-            "_id": "4de3f6bc5c292e601a12f0d8",
-            "pos": 16384,
-            "type": "check",
-            "name": "patch openid for async assoc storage"
-        }, {
-            "_id": "4de3f6cb5c292e601a12f21e",
-            "pos": 32768,
-            "type": "check",
-            "name": "trellis change to use Redis to store assocs"
-        }],
-        "name": "Checklist"
-    }, {
-        "checkItems": [],
-        "_id": "4de4e54df38ea2ed1f02d946",
-        "name": "Checklist"
-    }, {
-        "_id": "4de53731c1955d252209ffc8",
-        "checkItems": [{
-            "_id": "4de5375cc1955d25220a17c7",
-            "name": "account.js [Aaron]",
-            "pos": 16384,
-            "type": "check"
-        }, {
-            "_id": "4de5375ec1955d25220a1908",
-            "name": "ajaxRpc.js [Aaron]",
-            "pos": 32768,
-            "type": "check"
-        }, {
-            "_id": "4de5376bc1955d25220a1ba9",
-            "name": "packager.js (Ian)",
-            "pos": 49152,
-            "type": "check"
-        }, {
-            "_id": "4de53770c1955d25220a1cee",
-            "name": "permissions.js (Ian)",
-            "pos": 65536,
-            "type": "check"
-        }, {
-            "_id": "4de53775c1955d25220a1e38",
-            "name": "rpc.js (daniel)",
-            "pos": 81920,
-            "type": "check"
-        }, {
-            "_id": "4de5377ac1955d25220a1f84",
-            "name": "schema.js (daniel)",
-            "pos": 98304,
-            "type": "check"
-        }, {
-            "_id": "4de5377fc1955d25220a20cf",
-            "name": "sessions.js [Brett]",
-            "pos": 114688,
-            "type": "check"
-        }, {
-            "_id": "4de53783c1955d25220a22b4",
-            "name": "sockets.js (Ian)",
-            "pos": 131072,
-            "type": "check"
-        }],
-        "name": "/server"
-    }, {
-        "_id": "4de5373ec1955d25220a0b89",
-        "checkItems": [{
-            "_id": "4de538f2c1955d25220a5985",
-            "name": "actionfilter.js - Not used right now, don't worry about it.",
-            "pos": 16384,
-            "type": "check"
-        }, {
-            "_id": "4de538f5c1955d25220a5ad6",
-            "name": "browser.js [Aaron]",
-            "pos": 32768,
-            "type": "check"
-        }, {
-            "_id": "4de538f7c1955d25220a5c26",
-            "name": "dates.js - see daniel first [Aaron]",
-            "pos": 49152,
-            "type": "check"
-        }, {
-            "_id": "4de538fdc1955d25220a5f8b",
-            "name": "search.js - Not used right now, don't worry about it.",
-            "pos": 81920,
-            "type": "check"
-        }],
-        "name": "/static/js/"
-    }, {
-        "_id": "4de53c77c1955d25220b2bad",
-        "checkItems": [{
-            "_id": "4de53c7ec1955d25220b3770",
-            "name": "trellis.js [Aaron]",
-            "pos": 16384,
-            "type": "check"
-        }],
-        "name": "/"
-    }, {
-        "_id": "4de695be3ecfb79a26086cfa",
-        "checkItems": [{
-            "_id": "4de695d23ecfb79a260881e2",
-            "name": "closureCompiler.js (Ian)",
-            "pos": 16384,
-            "type": "check"
-        }, {
-            "_id": "4de695da3ecfb79a26088348",
-            "name": "bundle.js [brett]",
-            "pos": 32768,
-            "type": "check"
-        }, {
-            "_id": "4de695de3ecfb79a26088546",
-            "name": "gzipResponse.js (brett)",
-            "pos": 49152,
-            "type": "check"
-        }, {
-            "_id": "4de695f53ecfb79a26088a5a",
-            "name": "auth.js (Ian)",
-            "pos": 65536,
-            "type": "check"
-        }, {
-            "_id": "4de90b954cd033ab2d196a21",
-            "pos": 81920,
-            "type": "check",
-            "name": "emailusers/emailusers.js (brett)"
-        }],
-        "name": "/modules"
-    }, {
-        "_id": "4de8f7474cd033ab2d1431cd",
-        "checkItems": [{
-            "_id": "4de8f7524cd033ab2d146f97",
-            "pos": 16384,
-            "type": "check",
-            "name": "Org profile"
-        }, {
-            "_id": "4de8f7594cd033ab2d1475e4",
-            "pos": 32768,
-            "type": "check",
-            "name": "Create org"
-        }, {
-            "_id": "4de8f7704cd033ab2d147d18",
-            "pos": 49152,
-            "type": "check",
-            "name": "List of orgs in member profile"
-        }, {
-            "_id": "4de8f77c4cd033ab2d147f5b",
-            "pos": 65536,
-            "type": "check",
-            "name": "List of org boards in member profile"
-        }, {
-            "_id": "4de8f7824cd033ab2d1480dd",
-            "name": "Preferences: perms for features, visibility",
-            "pos": 81920,
-            "type": "check"
-        }, {
-            "_id": "4de8f7c44cd033ab2d14982f",
-            "pos": 98304,
-            "type": "check",
-            "name": "New board: option to make part of org"
-        }, {
-            "_id": "4de8f8244cd033ab2d149f0c",
-            "name": "Move/add board to org (in board preferences)",
-            "pos": 114688,
-            "type": "check"
-        }, {
-            "_id": "4de8f82a4cd033ab2d14a096",
-            "name": "Manage org members page",
-            "pos": 131072,
-            "type": "check"
-        }, {
-            "_id": "4de94253d7b3339b2f11cf9b",
-            "pos": 147456,
-            "type": "check",
-            "name": "Org account page"
-        }, {
-            "_id": "4df8ed9adc894c716d1ccc78",
-            "pos": 163840,
-            "type": "check",
-            "name": "Enforce that orgs and members can't have the same name: first claimer wins"
-        }, {
-            "_id": "4e035aba8d64cbf7834194d3",
-            "pos": 180224,
-            "type": "check",
-            "name": "'Add Board' from the org page"
-        }, {
-            "_id": "4e035aeb8d64cbf78341c4ff",
-            "pos": 196608,
-            "type": "check",
-            "name": "Email template changes for org invite"
-        }, {
-            "_id": "4e035afa8d64cbf78341d835",
-            "pos": 212992,
-            "type": "check",
-            "name": "Allow you to join Trellis if you're invited to an org"
-        }, {
-            "_id": "4e035b978d64cbf783420ab1",
-            "pos": 229376,
-            "type": "check",
-            "name": "Make org boards show up in 'Boards' menu"
-        }, {
-            "_id": "4e035c888d64cbf783424ea0",
-            "pos": 245760,
-            "type": "check",
-            "name": "Feels like an organization header on the boards page should take me to the page for the org"
-        }, {
-            "_id": "4e035d088d64cbf7834269e4",
-            "pos": 262144,
-            "type": "check",
-            "name": "Consolidate joinBoard / joinOrganization templates"
-        }, {
-            "_id": "4e035f718d64cbf78342d8f3",
-            "pos": 278528,
-            "type": "check",
-            "name": "With Ian, figure out how to merge board and org invitation mgmt more"
-        }],
-        "name": "UI"
-    }, {
-        "_id": "4df21c86f07016d15a01b030",
-        "checkItems": [{
-            "_id": "4df21c91f07016d15a01c8eb",
-            "pos": 16384,
-            "type": "check",
-            "name": "Get trellis running on one FreeBSD server"
-        }, {
-            "_id": "4df21cadf07016d15a01d6c2",
-            "pos": 32768,
-            "type": "check",
-            "name": "Get both servers running pointing to the same mongo and redis"
-        }, {
-            "_id": "4df21ccaf07016d15a01e471",
-            "pos": 49152,
-            "type": "check",
-            "name": "Load balance"
-        }, {
-            "_id": "4df21cd7f07016d15a01f13c",
-            "pos": 65536,
-            "type": "check",
-            "name": "Test new setup"
-        }, {
-            "_id": "4df21ce4f07016d15a020b6d",
-            "name": "Flip DNS and adjust NAT [shawn] Tomorrow first thing.",
-            "pos": 98304,
-            "type": "check"
-        }, {
-            "_id": "4df25601839542cf5a106682",
-            "pos": 114688,
-            "type": "check",
-            "name": "Build node_modules for BSD 8.2"
-        }, {
-            "_id": "4df60eeac204e79d5d2a3713",
-            "pos": 131072,
-            "type": "check",
-            "name": "FreeBSD build machine"
-        }, {
-            "_id": "4df6332b8676f5a05d30cc80",
-            "name": "Fix node.js FreeBSD link issue to get hiredis, forever, and native bson parser working again. http://www.freebsd.org/cgi/query-pr.cgi?pr=157875",
-            "pos": 147456,
-            "type": "check"
-        }, {
-            "_id": "4df7bd69e5c8fa736d0b4323",
-            "pos": 163840,
-            "type": "check",
-            "name": "Build with kqueue"
-        }, {
-            "_id": "4df7c062e5c8fa736d0b8169",
-            "pos": 180224,
-            "type": "check",
-            "name": "re-enable backup-on-push in the bsd branch once we have perms"
-        }, {
-            "_id": "4df8be3edc894c716d12102f",
-            "name": "Issue pull request to ry for kqueue patch. https://github.com/joyent/node/pull/1186",
-            "pos": 196608,
-            "type": "check"
-        }, {
-            "_id": "4df8e529dc894c716d1a308c",
-            "pos": 212992,
-            "type": "check",
-            "name": "sockets are disconnected after a few seconds when going through HAProxy[shawn]"
-        }, {
-            "_id": "4df90c7fdc894c716d21a98d",
-            "name": "Allow trellisny3 and ny2 to connect to trellisny1's mongo and redis so that we can move servers without burning the ships. [shawn] http://our.fogbugz.com/default.asp?2076170",
-            "pos": 229376,
-            "type": "check"
-        }, {
-            "_id": "4df91169dc894c716d21eea7",
-            "name": "Send keepalives over open sockets every 30 minutes, b/c HAProxy will time out idle connections after an hour.[brett]",
-            "pos": 245760,
-            "type": "check"
-        }, {
-            "_id": "4dfa3772ee196e34f901c9e3",
-            "pos": 262144,
-            "type": "check",
-            "name": "When connected to trellis on the new servers: you do something and don't see it refected in the activity feed"
-        }, {
-            "_id": "4dfa676b959e5c5cfc055192",
-            "pos": 278528,
-            "type": "check",
-            "name": "Cut over to redis on trellisny2"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4df69f0e8676f5a05d39da78",
-        "checkItems": [{
-            "_id": "4df6a02d8676f5a05d3a0f4f",
-            "pos": 16384,
-            "type": "check",
-            "name": "Clicking any input on /login redirects to /authenticate, expected /confirmedNewMember for create account"
-        }, {
-            "_id": "4df6a0e08676f5a05d3a2169",
-            "pos": 32768,
-            "type": "check",
-            "name": "Whitelisted, non-google email address (I tried yahoo) redirect to '/login?returnUrl=/authenticate' on create account."
-        }, {
-            "_id": "4df6a4508676f5a05d3a4b8e",
-            "name": "Attempting to sign in with google goes to /verify, then immediately redirects to /login?returnUrl=/verify (broken on fresh db, worked on old db)",
-            "pos": 49152,
-            "type": "check"
-        }],
-        "name": "Bugz"
-    }, {
-        "_id": "4df8bc8ddc894c716d110817",
-        "checkItems": [{
-            "_id": "4df8bc99dc894c716d111ec9",
-            "pos": 16384,
-            "type": "check",
-            "name": "Test env on trellis-build"
-        }, {
-            "_id": "4df8bcafdc894c716d112b66",
-            "name": "scripts to start server and blank DB",
-            "pos": 32768,
-            "type": "check"
-        }, {
-            "_id": "4df8bcc2dc894c716d11373c",
-            "pos": 49152,
-            "type": "check",
-            "name": "VPN"
-        }, {
-            "_id": "4df8bccedc894c716d1143ce",
-            "pos": 65536,
-            "type": "check",
-            "name": "account on trellis-build"
-        }, {
-            "_id": "4df8bcd2dc894c716d114f8d",
-            "pos": 81920,
-            "type": "check",
-            "name": "instructions"
-        }, {
-            "_id": "4df8c75adc894c716d143849",
-            "pos": 98304,
-            "type": "check",
-            "name": "ourdot access"
-        }, {
-            "_id": "4dfb8ccae01b09000006e102",
-            "pos": 114688,
-            "type": "check",
-            "name": "script to hg pull/up"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dfb6db01c2ab8000003041f",
-        "checkItems": [{
-            "_id": "4dfb6dbb1c2ab80000031d46",
-            "pos": 16384,
-            "type": "check",
-            "name": "Close board"
-        }, {
-            "_id": "4dfb6dbf1c2ab80000032b7b",
-            "pos": 32768,
-            "type": "check",
-            "name": "change name"
-        }, {
-            "_id": "4dfb6dc31c2ab800000338e3",
-            "pos": 49152,
-            "type": "check",
-            "name": "change preferences"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dff859729bde2224901cc9e",
-        "checkItems": [{
-            "_id": "4dff85b229bde2224901eaaa",
-            "pos": 16384,
-            "type": "check",
-            "name": "People are listed as 'active' who haven't logged in for days"
-        }, {
-            "_id": "4dff85c629bde2224901fa21",
-            "pos": 32768,
-            "type": "check",
-            "name": "only 4 procs are showing up in liveprocs"
-        }, {
-            "_id": "4dff85f029bde22249020b47",
-            "pos": 49152,
-            "type": "check",
-            "name": "status entries without a liveprocs entry are still not being deleted"
-        }, {
-            "_id": "4dff864b29bde222490226f5",
-            "pos": 65536,
-            "type": "check",
-            "name": "however, we do not see any status entries with an incorrect status in Redis"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4dffa67d079f66be4b04bb5a",
-        "checkItems": [{
-            "_id": "4dffa688079f66be4b04da43",
-            "pos": 16384,
-            "type": "check",
-            "name": "Better behavior when setting password for existing account"
-        }, {
-            "_id": "4dffa68f079f66be4b04ea2f",
-            "pos": 32768,
-            "type": "check",
-            "name": "No duplicate-email accounts"
-        }, {
-            "_id": "4dffa69f079f66be4b04fa20",
-            "pos": 49152,
-            "type": "check",
-            "name": "Feedback that password change occurred"
-        }, {
-            "_id": "4dffa6ad079f66be4b050ae8",
-            "pos": 65536,
-            "type": "check",
-            "name": "Feedback that the username or password was incorrect on login"
-        }, {
-            "_id": "4e00c20c079f66bb4b0f1148",
-            "pos": 81920,
-            "type": "check",
-            "name": "Fix styles for incorrect login message"
-        }, {
-            "_id": "4e00d4ef079f66bc4b154c82",
-            "pos": 98304,
-            "type": "check",
-            "name": "email account confirmation"
-        }, {
-            "_id": "4e00dffb079f66be4b14d9a0",
-            "pos": 114688,
-            "type": "check",
-            "name": "allow you to create a non-openid user with a password"
-        }, {
-            "_id": "4e00f93117baf6ee6603162f",
-            "pos": 131072,
-            "type": "check",
-            "name": "forgot password page"
-        }, {
-            "_id": "4e09f16685ad212f9adcc3c3",
-            "pos": 147456,
-            "type": "check",
-            "name": "Allow account creation for any email with invite code"
-        }, {
-            "_id": "4e0cc02737796f0000214c74",
-            "pos": 163840,
-            "type": "check",
-            "name": "Dial with CR comment from http://our.fogbugz.com/kiln/Review/2075267"
-        }, {
-            "_id": "4e14beb29df22bbd48037a16",
-            "name": "No account confirmation [deferred for now]",
-            "pos": 180224,
-            "type": "check"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e0dd9d6ca68f50000034cc7",
-        "checkItems": [{
-            "_id": "4e0dd9dcca68f50000036f68",
-            "pos": 16384,
-            "type": "check",
-            "name": "Can't reopen closed boards"
-        }, {
-            "_id": "4e0dd9f4ca68f50000039479",
-            "pos": 49152,
-            "type": "check",
-            "name": "When you DO reopen a closed board from a different page, it's blank until you reload"
-        }, {
-            "_id": "4e0dd9fcca68f5000003a6cd",
-            "pos": 65536,
-            "type": "check",
-            "name": "Reopening a board should just take you to the board"
-        }],
-        "name": "Checklist"
-    }, {
-        "checkItems": [],
-        "_id": "4e1457780855bfafa8020b9d",
-        "name": "Checklist"
-    }, {
-        "_id": "4e1457790855bfafa8022037",
-        "checkItems": [{
-            "_id": "4e1457ad0855bfafa802c424",
-            "pos": 16384,
-            "type": "check",
-            "name": "Board Preferences -> Better alignment/spacing on add to org"
-        }, {
-            "_id": "4e14582e0855bfafa8033196",
-            "name": "Some way to get to the organization's page from the board (for org members)",
-            "pos": 32768,
-            "type": "check"
-        }, {
-            "_id": "4e146ba79b22b2b94800e2cb",
-            "name": "Make org name show up in 'Boards' menu",
-            "pos": 49152,
-            "type": "check"
-        }, {
-            "_id": "4e146bbc8e237d0eaa00fa9c",
-            "pos": 65536,
-            "type": "check",
-            "name": "With Ian, figure out how to merge board and org invitation mgmt more"
-        }, {
-            "_id": "4e146bc6c3dce0b84801a9cd",
-            "pos": 81920,
-            "type": "check",
-            "name": "Member status changes update immediately"
-        }, {
-            "_id": "4e147dda9b22b2ba480955f2",
-            "pos": 98304,
-            "type": "check",
-            "name": "Admin page: org stats"
-        }, {
-            "_id": "4e14a160018bc307aa072caa",
-            "pos": 114688,
-            "type": "check",
-            "name": "Only allow org admins to see :org/members and :org/account"
-        }, {
-            "_id": "4e14b508b809c7dbab083e73",
-            "pos": 131072,
-            "type": "check",
-            "name": "Public view of org (org and private boards hidden to non-orgers, members are shown)"
-        }],
-        "name": "Checklist"
-    }, {
-        "checkItems": [],
-        "_id": "4e17350dec9833696c04aa79",
-        "name": "Checklist"
-    }, {
-        "_id": "4e17350fec9833696c04c94a",
-        "checkItems": [{
-            "_id": "4e173527ec9833696c0524f7",
-            "pos": 16384,
-            "type": "check",
-            "name": "Make sure non-socket-connected browsers catch the upgrade"
-        }, {
-            "_id": "4e17352dec9833696c053a3b",
-            "pos": 32768,
-            "type": "check",
-            "name": "reconnect gracefully"
-        }, {
-            "_id": "4e17353bec9833696c054f8a",
-            "pos": 49152,
-            "type": "check",
-            "name": "detect version bump and gently ask the user to click to upgrade"
-        }, {
-            "_id": "4e28af81ce64d1930a014150",
-            "pos": 83360,
-            "type": "check",
-            "name": "Sync subscribed models on socket-connected browsers"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e1b53e4274d60b9dd06b281",
-        "checkItems": [{
-            "_id": "4e1b53f5274d60b9dd071ada",
-            "pos": 16384,
-            "type": "check",
-            "name": "Notifications"
-        }, {
-            "_id": "4e1b53fc274d60b9dd072d6b",
-            "pos": 32768,
-            "type": "check",
-            "name": "Invitation"
-        }, {
-            "_id": "4e1b5404274d60b9dd073ff1",
-            "pos": 49152,
-            "type": "check",
-            "name": "Org Permission Level"
-        }, {
-            "_id": "4e1b5407274d60b9dd07526c",
-            "pos": 65536,
-            "type": "check",
-            "name": "Archive"
-        }, {
-            "_id": "4e1bce84a5a5a4000003c761",
-            "pos": 81920,
-            "type": "check",
-            "name": "Search"
-        }, {
-            "_id": "4e1bd069a5a5a4000003fcab",
-            "pos": 98304,
-            "type": "check",
-            "name": "Label (large)"
-        }],
-        "name": "Icons"
-    }, {
-        "checkItems": [],
-        "_id": "4e1b53e5274d60b9dd06cd0d",
-        "name": "Checklist"
-    }, {
-        "_id": "4e1c52928d677cfe8300697d",
-        "checkItems": [{
-            "_id": "4e1c52ad8d677cfe83008e73",
-            "pos": 16384,
-            "type": "check",
-            "name": "Still have to keep dragging the card to keep it scrolling -- holding it over the bottom or top of the list doesn't scroll"
-        }, {
-            "_id": "4e1c52bf8d677cfe8300a1d4",
-            "pos": 32768,
-            "type": "check",
-            "name": "Single-col still doesn't scroll"
-        }, {
-            "_id": "4e1dcb277b2050df84026134",
-            "pos": 50033,
-            "type": "check",
-            "name": "ie doesn't scroll"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e1c959c9a872d028402dbb8",
-        "checkItems": [{
-            "_id": "4e1c95ac9a872d0284030358",
-            "pos": 16384,
-            "type": "check",
-            "name": "the \"Archive\" button in the sidebar looks like it might archive the board"
-        }, {
-            "_id": "4e1c95b49a872d028403183e",
-            "pos": 32768,
-            "type": "check",
-            "name": "closed cards say \"reopen\""
-        }, {
-            "_id": "4e1c96489a872d0284046c6c",
-            "pos": 65536,
-            "type": "check",
-            "name": "list menu says \"close list\""
-        }, {
-            "_id": "4e1c96566adf53fa83160ba6",
-            "pos": 81920,
-            "type": "check",
-            "name": "hover over archive button on card says \"Close card\""
-        }, {
-            "_id": "4e1c967b9a872d0284048163",
-            "pos": 98304,
-            "type": "check",
-            "name": "The long-hold menu uses the old close icon"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e1d7fb662429ee21c02f483",
-        "checkItems": [{
-            "_id": "4e1d7fbe62429ee21c031e63",
-            "pos": 17314,
-            "type": "check",
-            "name": "Show date uploaded"
-        }, {
-            "_id": "4e1d7fc362429ee21c03346f",
-            "pos": 34198,
-            "type": "check",
-            "name": "Most recent file at top"
-        }, {
-            "_id": "4e1d7fd162429ee21c034a7d",
-            "pos": 51067,
-            "type": "check",
-            "name": "Delete attachments"
-        }, {
-            "_id": "4e1d7fdf62429ee21c03608d",
-            "pos": 67484,
-            "type": "check",
-            "name": "Show previews of attachment in action?"
-        }, {
-            "_id": "4e1dddbd802ec6e81c057d93",
-            "pos": 84038,
-            "type": "check",
-            "name": "Fix previews for deleted attachments"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e1f0b467c741f95300199a6",
-        "checkItems": [{
-            "_id": "4e1f0b787c741f953001ca06",
-            "name": "Add helper text to org section of 'new board' page, include link to create org page.",
-            "pos": 16415,
-            "type": "check"
-        }, {
-            "_id": "4e1f0bdf7c741f9530024340",
-            "name": "Add create org link on member boards page",
-            "pos": 33562,
-            "type": "check"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e20882da43ec975a00594c0",
-        "checkItems": [{
-            "_id": "4e208831a43ec975a005c1c2",
-            "pos": 16520,
-            "type": "check",
-            "name": "Profile of others has incomplete actions list"
-        }, {
-            "_id": "4e208836a43ec975a005d968",
-            "pos": 33602,
-            "type": "check",
-            "name": "Initial board load prefs"
-        }, {
-            "_id": "4e208851a43ec975a005f115",
-            "pos": 50465,
-            "type": "check",
-            "name": "No document may grow without bound or we will eventually bump MongoDB's 16MB limit"
-        }],
-        "name": "Checklist"
-    }, {
-        "checkItems": [],
-        "_id": "4e31abbd44e04eb4f00c7627",
-        "name": "Checklist"
-    }, {
-        "_id": "4e31abbe44e04eb4f00c96fe",
-        "checkItems": [{
-            "_id": "4e31abd544e04eb4f00cc734",
-            "pos": 16928,
-            "type": "check",
-            "name": "Client takes a long time to figure out it's not connected"
-        }],
-        "name": "Checklist"
-    }, {
-        "checkItems": [],
-        "_id": "4e36b73a115cc20000019c3a",
-        "name": "Checklist"
-    }, {
-        "_id": "4e723f7dec7bba0000151903",
-        "checkItems": [{
-            "_id": "4e723f8aec7bba0000155231",
-            "pos": 17392,
-            "type": "check",
-            "name": "Become invisible to people who don't know my email address"
-        }, {
-            "_id": "4e723f9dec7bba0000159cb6",
-            "pos": 34459,
-            "type": "check",
-            "name": "Become invisible to people who I don't share a board/org with."
-        }, {
-            "_id": "4e723fb1eb752c26d615d10b",
-            "pos": 51840,
-            "type": "check",
-            "name": "Make it so outsiders can't see what orgs I belong to."
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e7a20cb07fb4fc4c2019fc9",
-        "checkItems": [{
-            "_id": "4e7a20cf4003bbbbc200af97",
-            "pos": 33965,
-            "type": "check",
-            "name": "2"
-        }, {
-            "_id": "4e7a20d06573bfc3c200013d",
-            "pos": 51219,
-            "type": "check",
-            "name": "3"
-        }, {
-            "_id": "4e7a20d207fb4fc4c201bf51",
-            "pos": 16825,
-            "type": "check",
-            "name": "1"
-        }, {
-            "_id": "4e7b97db87f962e71d023066",
-            "pos": 67767,
-            "type": "check",
-            "name": "4"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4e95e0160fa46da8a6001c46",
-        "checkItems": [{
-            "_id": "4e95e0170fa46da8a6002026",
-            "pos": 17372,
-            "type": "check",
-            "name": "1"
-        }, {
-            "_id": "4e95e0180fa46da8a60022a7",
-            "pos": 34778,
-            "type": "check",
-            "name": "2"
-        }, {
-            "_id": "4e95e0180fa46da8a600252a",
-            "pos": 51336,
-            "type": "check",
-            "name": "3"
-        }, {
-            "_id": "4e95e0180fa46da8a60027af",
-            "pos": 68195,
-            "type": "check",
-            "name": "4"
-        }, {
-            "_id": "4e95e0190fa46da8a6002a36",
-            "pos": 85418,
-            "type": "check",
-            "name": "45"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4edf81719dfadf92ba00043f",
-        "checkItems": [{
-            "_id": "4edf81739dfadf92ba00086e",
-            "pos": 16681,
-            "type": "check",
-            "name": "a"
-        }, {
-            "_id": "4edf81749dfadf92ba000afd",
-            "pos": 33089,
-            "type": "check",
-            "name": "b"
-        }, {
-            "_id": "4edf81749dfadf92ba000d8e",
-            "pos": 49707,
-            "type": "check",
-            "name": "c"
-        }, {
-            "_id": "4edf8194406a1093ba000a7c",
-            "pos": 66874,
-            "type": "check",
-            "name": "d"
-        }, {
-            "_id": "4edf8194406a1093ba000d17",
-            "pos": 83580,
-            "type": "check",
-            "name": "e"
-        }, {
-            "_id": "4edf8195406a1093ba000fb7",
-            "pos": 100642,
-            "type": "check",
-            "name": "f"
-        }, {
-            "_id": "4edf8195406a1093ba001256",
-            "pos": 117840,
-            "type": "check",
-            "name": "g"
-        }],
-        "name": "ok"
-    }, {
-        "_id": "4edf81a6406a1093ba0019d4",
-        "checkItems": [{
-            "_id": "4edf81b1406a1093ba00210b",
-            "pos": 16855,
-            "type": "check",
-            "name": "neato!"
-        }],
-        "name": "oh yeah?"
-    }, {
-        "_id": "4ee78a30fd0f210000002a81",
-        "checkItems": [{
-            "_id": "4ee78a36fd0f210000002ea4",
-            "pos": 16858,
-            "type": "check",
-            "name": "Hello"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4f3182e705a3340b64000c26",
-        "checkItems": [{
-            "_id": "4f3182ea05a3340b640010b0",
-            "pos": 17025,
-            "type": "check",
-            "name": "a"
-        }, {
-            "_id": "4f3182eb05a3340b64001690",
-            "pos": 92449,
-            "type": "check",
-            "name": "c"
-        }, {
-            "_id": "4f3182eb05a3340b64001983",
-            "pos": 67076,
-            "type": "check",
-            "name": "d"
-        }, {
-            "_id": "4f3182ec05a3340b64001c78",
-            "pos": 83917,
-            "type": "check",
-            "name": "e"
-        }, {
-            "_id": "4f3182ed05a3340b64001f6f",
-            "pos": 100981,
-            "type": "check",
-            "name": "f"
-        }, {
-            "_id": "4f318ed87568566268000753",
-            "pos": 117775,
-            "type": "check",
-            "name": "g"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4f3182ef05a3340b64002267",
-        "checkItems": [{
-            "_id": "4f3182f105a3340b64002706",
-            "pos": 16481,
-            "type": "check",
-            "name": "1"
-        }, {
-            "_id": "4f3182f205a3340b64002a03",
-            "pos": 33604,
-            "type": "check",
-            "name": "2"
-        }, {
-            "_id": "4f3182f205a3340b64002d02",
-            "pos": 50212,
-            "type": "check",
-            "name": "3"
-        }, {
-            "_id": "4f3182f205a3340b64003003",
-            "pos": 67495,
-            "type": "check",
-            "name": "4"
-        }, {
-            "_id": "4f3182f305a3340b64003306",
-            "pos": 84844,
-            "type": "check",
-            "name": "5"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4f318f5f75685662680020ea",
-        "checkItems": [{
-            "_id": "4f318f6275685662680025a2",
-            "pos": 17401,
-            "type": "check",
-            "name": "a"
-        }, {
-            "_id": "4f318f6275685662680028ad",
-            "pos": 34370,
-            "type": "check",
-            "name": "b"
-        }, {
-            "_id": "4f318f627568566268002bba",
-            "pos": 51592,
-            "type": "check",
-            "name": "c"
-        }, {
-            "_id": "4f318f637568566268002ec9",
-            "pos": 68597,
-            "type": "check",
-            "name": "d"
-        }, {
-            "_id": "4f318f6475685662680031da",
-            "pos": 85739,
-            "type": "check",
-            "name": "e"
-        }, {
-            "_id": "4f318f6475685662680034ed",
-            "pos": 102588,
-            "type": "check",
-            "name": "f"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4f357bc7f712566521002a28",
-        "checkItems": [],
-        "name": "ije"
-    }, {
-        "checkItems": [],
-        "_id": "4f357bd1f71256652100320f",
-        "name": "lolz"
-    }, {
-        "checkItems": [],
-        "_id": "4f3a7141e1d0033072000257",
-        "name": "Checklist"
-    }, {
-        "_id": "4f3a7142e1d00330720008d6",
-        "checkItems": [{
-            "_id": "4f3a7146e1d0033072000da8",
-            "pos": 65536,
-            "type": "check",
-            "name": "1"
-        }, {
-            "_id": "4f3a7149e1d0033072001225",
-            "pos": 33102,
-            "type": "check",
-            "name": "2"
-        }, {
-            "_id": "4f3a714ae1d00330720016a5",
-            "pos": 49702,
-            "type": "check",
-            "name": "3"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4f3a75b94a2915db72000c7f",
-        "checkItems": [{
-            "_id": "4f3a75c94a2915db72001315",
-            "pos": 16815,
-            "type": "check",
-            "name": "1"
-        }, {
-            "_id": "4f3a75cb4a2915db7200179e",
-            "pos": 33925,
-            "type": "check",
-            "name": "2"
-        }, {
-            "_id": "4f3a75cc4a2915db72001c2a",
-            "pos": 50337,
-            "type": "check",
-            "name": "3"
-        }, {
-            "_id": "4f3a75e54991753c730001d0",
-            "pos": 67169,
-            "type": "check",
-            "name": "4"
-        }, {
-            "_id": "4f3a75f64991753c73000d69",
-            "pos": 84551,
-            "type": "check",
-            "name": "5"
-        }, {
-            "_id": "4f3a7621814abb4d73001252",
-            "pos": 101594,
-            "type": "check",
-            "name": "6"
-        }, {
-            "_id": "4f3a763e814abb4d7300239c",
-            "pos": 118958,
-            "type": "check",
-            "name": "7"
-        }, {
-            "_id": "4f3a79b71f2bbfba730001f0",
-            "pos": 136130,
-            "type": "check",
-            "name": "8"
-        }, {
-            "_id": "4f3a79d01f2bbfba73000a88",
-            "pos": 152632,
-            "type": "check",
-            "name": "9"
-        }, {
-            "_id": "4f3a7a3e1797fc09740005cc",
-            "pos": 169985,
-            "type": "check",
-            "name": "10"
-        }, {
-            "_id": "4f3a7ba03893916574004908",
-            "pos": 187334,
-            "type": "check",
-            "name": "11"
-        }, {
-            "_id": "4f3a7d296f873c9f74002ce5",
-            "pos": 204306,
-            "type": "check",
-            "name": "12"
-        }, {
-            "_id": "4f3a7d296f873c9f7400318f",
-            "pos": 221278,
-            "type": "check",
-            "name": "13"
-        }, {
-            "_id": "4f3a7d2a6f873c9f7400363c",
-            "pos": 238543,
-            "type": "check",
-            "name": "14"
-        }, {
-            "_id": "4f3a882edf73c6a4410009e9",
-            "pos": 254942,
-            "type": "check",
-            "name": "15"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4f3a885ddf73c6a441002ce7",
-        "checkItems": [{
-            "_id": "4f3a8860df73c6a441003222",
-            "pos": 17221,
-            "type": "check",
-            "name": "a"
-        }, {
-            "_id": "4f3a8861df73c6a441003bd3",
-            "pos": 50893,
-            "type": "check",
-            "name": "c"
-        }, {
-            "_id": "4f3a8862df73c6a4410040b0",
-            "pos": 67457,
-            "type": "check",
-            "name": "d"
-        }, {
-            "_id": "4f3a8862df73c6a441004590",
-            "pos": 84067,
-            "type": "check",
-            "name": "e"
-        }, {
-            "_id": "4f3a8863df73c6a441004a73",
-            "pos": 100547,
-            "type": "check",
-            "name": "f"
-        }, {
-            "_id": "4f3a8863df73c6a441004f59",
-            "name": "grrrrrrrrrrrr",
-            "pos": 117713.5,
-            "type": "check"
-        }, {
-            "_id": "4f3d35c8e5f5419d10001e50",
-            "name": "h",
-            "pos": 66496.5,
-            "type": "check"
-        }, {
-            "_id": "4f425bd3ada835670e02256b",
-            "pos": 65536,
-            "type": "check",
-            "name": "1"
-        }, {
-            "name": "h",
-            "type": "check",
-            "pos": 134880,
-            "_id": "4f79f18711b5b71a58000a26"
-        }],
-        "name": "Checklister"
-    }, {
-        "name": "Checklist",
-        "_id": "4f711679661dd5ebc5004c86",
-        "checkItems": []
-    }, {
-        "_id": "4f95b7d74043f7b179006025",
-        "checkItems": [{
-            "name": "30% packet loss",
-            "type": "check",
-            "pos": 17398,
-            "_id": "4f95b7ec4043f7b17900637a"
-        }, {
-            "name": "just totally cuts out sometimes",
-            "type": "check",
-            "pos": 50968,
-            "_id": "4f95b7ed4043f7b179006849"
-        }, {
-            "name": "REALLY lots of latency",
-            "type": "check",
-            "pos": 33898,
-            "_id": "4f95b7edea9ef48b7c001c8a"
-        }, {
-            "name": "6",
-            "type": "check",
-            "pos": 152755,
-            "_id": "4f95b857ea9ef48b7c0021a0"
-        }, {
-            "name": "7",
-            "type": "check",
-            "pos": 169709,
-            "_id": "4f95b857ea9ef48b7c00267e"
-        }, {
-            "name": "8",
-            "type": "check",
-            "pos": 186988,
-            "_id": "4f95b858ea9ef48b7c002b5f"
-        }, {
-            "name": "9",
-            "type": "check",
-            "pos": 203481,
-            "_id": "4f95b858ea9ef48b7c003043"
-        }, {
-            "name": "1",
-            "type": "check",
-            "pos": 67700,
-            "_id": "4f95b858ea9ef48b7c00352a"
-        }, {
-            "name": "4",
-            "type": "check",
-            "pos": 118187,
-            "_id": "4f95b859ea9ef48b7c003a14"
-        }, {
-            "name": "5",
-            "type": "check",
-            "pos": 135566,
-            "_id": "4f95b859ea9ef48b7c003f01"
-        }, {
-            "name": "2",
-            "type": "check",
-            "pos": 84641,
-            "_id": "4f95b859ea9ef48b7c0043f1"
-        }, {
-            "name": "3",
-            "type": "check",
-            "pos": 101678,
-            "_id": "4f95b85aea9ef48b7c0048e4"
-        }],
-        "name": "Checklisterize"
-    }, {
-        "_id": "4fa03d6d023c0b2a6b00437d",
-        "checkItems": [{
-            "name": "One",
-            "type": "check",
-            "pos": 16384,
-            "_id": "4fa03d6f023c0b2a6b0048c1"
-        }, {
-            "name": "Two",
-            "type": "check",
-            "pos": 32768,
-            "_id": "4fa03d6f023c0b2a6b004db9"
-        }, {
-            "name": "Three",
-            "type": "check",
-            "pos": 49152,
-            "_id": "4fa03d70023c0b2a6b0052b4"
-        }],
-        "name": "Checklist"
-    }, {
-        "_id": "4fa03d79023c0b2a6b0061fc",
-        "checkItems": [{
-            "_id": "4fa03d7d023c0b2a6b007170",
-            "name": "Six Seven Eight Nine",
-            "pos": 49152,
-            "type": "check"
-        }],
-        "name": "Checklist"
-    }]
-}
diff --git a/benchmarks/clone.js b/benchmarks/clone.js
deleted file mode 100644
index 217f115341..0000000000
--- a/benchmarks/clone.js
+++ /dev/null
@@ -1,79 +0,0 @@
-'use strict';
-
-const mongoose = require('../');
-const Schema = mongoose.Schema;
-const Benchmark = require('benchmark');
-
-const DocSchema = new Schema({
-  title: String
-});
-
-const SimpleSchema = new Schema({
-  string: { type: String, required: true },
-  number: { type: Number, min: 10 }
-});
-
-const AllSchema = new Schema({
-  string: { type: String, required: true },
-  number: { type: Number, min: 10 },
-  date: Date,
-  bool: Boolean,
-  buffer: Buffer,
-  objectid: Schema.ObjectId,
-  array: Array,
-  strings: [String],
-  numbers: [Number],
-  dates: [Date],
-  bools: [Boolean],
-  buffers: [Buffer],
-  objectids: [Schema.ObjectId],
-  docs: {
-    type: [DocSchema], validate: function() {
-      return true;
-    }
-  },
-  s: { nest: String }
-});
-
-const A = mongoose.model('A', AllSchema);
-const a = new A({
-  string: 'hello world',
-  number: 444848484,
-  date: new Date(),
-  bool: true,
-  buffer: Buffer.alloc(0),
-  objectid: new mongoose.Types.ObjectId(),
-  array: [4, {}, [], 'asdfa'],
-  strings: ['one', 'two', 'three', 'four'],
-  numbers: [72, 6493, 83984643, 348282.55],
-  dates: [new Date(), new Date(), new Date()],
-  bools: [true, false, false, true, true],
-  buffers: [Buffer.from([33]), Buffer.from([12])],
-
-  objectids: [new mongoose.Types.ObjectId()],
-  docs: [{ title: 'yo' }, { title: 'nowafasdi0fas asjkdfla fa' }],
-  s: { nest: 'hello there everyone!' }
-});
-
-const Simple = mongoose.model('Simple', SimpleSchema);
-const simple = new Simple({
-  string: 'hello world',
-  number: 444848484
-});
-
-new Benchmark.Suite()
-  .add('Simple', function() {
-    simple.toObject({ depopulate: true });
-  })
-  .add('AllSchema', function() {
-    a.toObject({ depopulate: true });
-  })
-  .on('cycle', function(evt) {
-    if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-      console.log(String(evt.target));
-    }
-  })
-  .run();
-process.memoryUsage();
-
-// --trace-opt --trace-deopt --trace-bailout
\ No newline at end of file
diff --git a/benchmarks/create.js b/benchmarks/create.js
deleted file mode 100644
index 5a1bcb533b..0000000000
--- a/benchmarks/create.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// require('nodetime').profile();
-
-'use strict';
-
-const mongoose = require('../../mongoose');
-const Benchmark = require('benchmark');
-
-const Schema = mongoose.Schema;
-
-const CheckItem = new Schema({
-  name: { type: String },
-  type: { type: String },
-  pos: { type: Number }
-});
-
-const Checklist = new Schema({
-  name: { type: String },
-  checkItems: { type: [CheckItem] }
-});
-
-const Board = new Schema({
-  checklists: { type: [Checklist] }
-});
-
-const BoardModel = mongoose.model('Board', Board);
-const CheckItemModel = mongoose.model('CheckItem', CheckItem);
-const doc = require('./bigboard.json');
-
-new Benchmark.Suite()
-  .add('CheckItem', function() {
-    new CheckItemModel({
-      _id: '4daee8a2aae47fe55305eabf',
-      pos: 32768,
-      type: 'check',
-      name: 'delete checklists'
-    });
-  })
-  .add('Board', function() {
-    new BoardModel(doc);
-  })
-  .on('cycle', function(evt) {
-    if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-      console.log(String(evt.target));
-    }
-  })
-  .run();
diff --git a/benchmarks/index.js b/benchmarks/index.js
deleted file mode 100644
index 90521a52bd..0000000000
--- a/benchmarks/index.js
+++ /dev/null
@@ -1,151 +0,0 @@
-'use strict';
-
-Error.stackTraceLimit = Infinity;
-const out = process.argv.length < 3;
-function log() {
-  if (out) {
-    console.error.apply(console, arguments);
-  }
-}
-
-const mongoose = require('../');
-const Schema = mongoose.Schema;
-
-const DocSchema = new Schema({
-  title: String
-});
-
-const AllSchema = new Schema({
-  string: String,
-  number: Number,
-  date: Date,
-  bool: Boolean,
-  buffer: Buffer,
-  objectid: Schema.ObjectId,
-  array: Array,
-  strings: [String],
-  numbers: [Number],
-  dates: [Date],
-  bools: [Boolean],
-  buffers: [Buffer],
-  objectids: [Schema.ObjectId],
-  docs: [DocSchema]
-});
-
-const A = mongoose.model('A', AllSchema);
-
-let numdocs = 0;
-let totaltime = 0;
-
-// bench the normal way
-// the try building the doc into the document prototype
-// and using inheritance and bench that
-//
-// also, bench using listeners for each subdoc vs one
-// listener that knows about all subdocs and notifies
-// them.
-
-function run(label, fn) {
-  log('running %s', label);
-  let started = process.memoryUsage();
-  let start = new Date;
-  let total = 10000;
-  let i = total;
-  let a;
-  while (i--) {
-    a = fn();
-    if (i % 2) {
-      a.toObject({ depopulate: true });
-    } else {
-      if (a._delta) {
-        a._delta();
-      } else {
-        a.$__delta();
-      }
-    }
-  }
-  let time = (new Date - start) / 1000;
-  totaltime += time;
-  numdocs += total;
-  log(label + ' took %d seconds for %d docs (%d dps)', time, total, total / time);
-  let used = process.memoryUsage();
-  let res = {};
-  res.rss = used.rss - started.rss;
-  res.heapTotal = used.heapTotal - started.heapTotal;
-  res.heapUsed = used.heapUsed - started.heapUsed;
-  log('change: ', res);
-  a = res = used = time = started = start = total = i = null;
-}
-
-run('string', function() {
-  return new A({
-    string: 'hello world'
-  });
-});
-run('number', function() {
-  return new A({
-    number: 444848484
-  });
-});
-run('date', function() {
-  return new A({
-    date: new Date
-  });
-});
-run('bool', function() {
-  return new A({
-    bool: true
-  });
-});
-run('buffer', function() {
-  return new A({
-    buffer: Buffer.alloc(0)
-  });
-});
-run('objectid', function() {
-  return new A({
-    objectid: new mongoose.Types.ObjectId()
-  });
-});
-run('array of mixed', function() {
-  return new A({
-    array: [4, {}, [], 'asdfa']
-  });
-});
-run('array of strings', function() {
-  return new A({
-    strings: ['one', 'two', 'three', 'four']
-  });
-});
-run('array of numbers', function() {
-  return new A({
-    numbers: [72, 6493, 83984643, 348282.55]
-  });
-});
-run('array of dates', function() {
-  return new A({
-    dates: [new Date, new Date, new Date]
-  });
-});
-run('array of bools', function() {
-  return new A({
-    bools: [true, false, false, true, true]
-  });
-});
-run('array of buffers', function() {
-  return new A({
-    buffers: [Buffer.from([33]), Buffer.from([12])]
-  });
-});
-run('array of objectids', function() {
-  return new A({
-    objectids: [new mongoose.Types.ObjectId]
-  });
-});
-run('array of docs', function() {
-  return new A({
-    docs: [{ title: 'yo' }, { title: 'nowafasdi0fas asjkdfla fa' }]
-  });
-});
-
-console.error('completed %d docs in %d seconds (%d dps)', numdocs, totaltime, numdocs / totaltime);
\ No newline at end of file
diff --git a/benchmarks/mapOfSubdocs.js b/benchmarks/mapOfSubdocs.js
index 9fc6e40191..dc45001744 100644
--- a/benchmarks/mapOfSubdocs.js
+++ b/benchmarks/mapOfSubdocs.js
@@ -8,13 +8,12 @@ run().catch(err => {
 });
 
 async function run() {
-  await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_test', {
+  await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_benchmark', {
     serverSelectionTimeoutMS: 5000
   });
 
   const minisMap = new mongoose.Schema(
     {
-      //? Mini reference
       mini: {
         type: Map,
         of: new mongoose.Schema({
@@ -25,8 +24,6 @@ async function run() {
         }),
       },
     },
-    //? Automatic creation of timestamps for creation and updating.
-    //? This will be created on the background by the package
     { timestamps: true }
   );
   const MinisMap = mongoose.model('MinisMap', minisMap);
diff --git a/benchmarks/mem.js b/benchmarks/mem.js
deleted file mode 100644
index c73acac33e..0000000000
--- a/benchmarks/mem.js
+++ /dev/null
@@ -1,165 +0,0 @@
-'use strict';
-
-const mongoose = require('../');
-
-const Schema = mongoose.Schema;
-
-mongoose.connect('mongodb://127.0.0.1/mongoose-bench');
-
-const DocSchema = new Schema({
-  title: String
-});
-
-const AllSchema = new Schema({
-  string: { type: String, required: true },
-  number: { type: Number, min: 10 },
-  date: Date,
-  bool: Boolean,
-  buffer: Buffer,
-  objectid: Schema.ObjectId,
-  array: Array,
-  strings: [String],
-  numbers: [Number],
-  dates: [Date],
-  bools: [Boolean],
-  buffers: [Buffer],
-  objectids: [Schema.ObjectId],
-  docs: {
-    type: [DocSchema], validate: function() {
-      return true;
-    }
-  },
-  s: { nest: String }
-});
-
-const A = mongoose.model('A', AllSchema);
-
-const methods = [];
-methods.push(function(a, cb) {
-  A.findOne({ _id: a._id }, cb);
-}); // 2 MB
-methods.push(function(a, cb) {
-  A.find({ _id: a._id, bool: a.bool }, cb);
-}); // 3.8 MB
-methods.push(function(a, cb) {
-  A.findById(a._id, cb);
-}); // 4.6 MB
-methods.push(function(a, cb) {
-  A.where('number', a.number).limit(10).exec(cb);
-}); // 4.8 MB
-methods.push(function(a, cb) {
-  A.where('date', a.date).select('string').limit(10).exec(cb);
-}); // 3.5 mb
-methods.push(function(a, cb) {
-  A.where('date', a.date).select('string bool').limit(10).exec(cb);
-}); // 3.5 MB
-methods.push(function(a, cb) {
-  A.where('date', a.date).where('array').in(3).limit(10).exec(cb);
-}); // 1.82 MB
-methods.push(function(a, cb) {
-  A.updateOne({ _id: a._id }, { $addToset: { array: 'heeeeello' } }, cb);
-}); // 3.32 MB
-methods.push(function(a, cb) {
-  A.deleteOne({ _id: a._id }, cb);
-}); // 3.32 MB
-methods.push(function(a, cb) {
-  A.find().where('objectids').exists().select('dates').limit(10).exec(cb);
-}); // 3.32 MB
-methods.push(function(a, cb) {
-  A.count({ strings: a.strings[2], number: a.number }, cb);
-}); // 3.32 MB
-methods.push(function(a, cb) {
-  a.string = 'asdfaf';
-  a.number = 38383838;
-  a.date = new Date;
-  a.bool = false;
-  a.array.push(3);
-  a.dates.push(new Date);
-  // a.bools.push([true, false]);
-  a.docs.addToSet({ title: 'woot' });
-  a.strings.remove('three');
-  a.numbers.pull(72);
-  a.objectids.$pop();
-  a.docs.pull.apply(a.docs, a.docs);
-  a.s.nest = 'aooooooga';
-
-  if (i % 2) {
-    a.toObject({ depopulate: true });
-  } else {
-    if (a._delta) {
-      a._delta();
-    } else {
-      a.$__delta();
-    }
-  }
-
-  cb();
-});
-
-const started = process.memoryUsage();
-const start = new Date;
-const total = 10000;
-let i = total;
-
-function done() {
-  const time = (new Date - start);
-  const used = process.memoryUsage();
-
-  const res = {};
-  res.rss = used.rss - started.rss;
-  res.heapTotal = used.heapTotal - started.heapTotal;
-  res.heapUsed = used.heapUsed - started.heapUsed;
-
-  console.error('took %d ms for %d docs (%d dps)', time, total, total / (time / 1000), 'change: ', res);
-
-  mongoose.connection.db.dropDatabase(function() {
-    mongoose.connection.close();
-  });
-}
-
-function cycle() {
-  if (i-- === 0) {
-    return done();
-  }
-  let a = new A({
-    string: 'hello world',
-    number: 444848484,
-    date: new Date,
-    bool: true,
-    buffer: Buffer.alloc(0),
-    objectid: new mongoose.Types.ObjectId(),
-    array: [4, {}, [], 'asdfa'],
-    strings: ['one', 'two', 'three', 'four'],
-    numbers: [72, 6493, 83984643, 348282.55],
-    dates: [new Date, new Date, new Date],
-    bools: [true, false, false, true, true],
-    buffers: [Buffer.from([33]), Buffer.from([12])],
-    objectids: [new mongoose.Types.ObjectId],
-    docs: [{ title: 'yo' }, { title: 'nowafasdi0fas asjkdfla fa' }]
-  });
-
-  a.save(function() {
-    methods[Math.random() * methods.length | 0](a, function() {
-      a = null;
-      process.nextTick(cycle);
-    });
-  });
-
-  /* if (i%2)
-    a.toObject({ depopulate: true });
-  else
-    a._delta();
-
-  if (!(i%50)) {
-    var u = process.memoryUsage();
-    console.error('rss: %d, vsize: %d, heapTotal: %d, heapUsed: %d',
-        u.rss, u.vsize, u.heapTotal, u.heapUsed);
-  } */
-}
-
-mongoose.connection.on('open', function() {
-  mongoose.connection.db.dropDatabase(function() {
-    cycle();
-    // --trace-opt --trace-deopt --trace-bailout
-  });
-});
diff --git a/benchmarks/populate.js b/benchmarks/populate.js
deleted file mode 100644
index 2be29e72e0..0000000000
--- a/benchmarks/populate.js
+++ /dev/null
@@ -1,84 +0,0 @@
-'use strict';
-const mongoose = require('../');
-const Schema = mongoose.Schema;
-const docs = process.argv[2] ? process.argv[2] | 0 : 100;
-
-const A = mongoose.model('A', Schema({ name: 'string' }));
-
-const nested = Schema({
-  a: { type: Schema.ObjectId, ref: 'A' }
-});
-
-const B = mongoose.model('B', Schema({
-  as: [{ type: Schema.ObjectId, ref: 'A' }],
-  a: { type: Schema.ObjectId, ref: 'A' },
-  nested: [nested]
-}));
-
-let start;
-let count = 0;
-
-mongoose.connect('mongodb://127.0.0.1/mongoose-bench', function(err) {
-  if (err) {
-    return done(err);
-  }
-
-  A.create({ name: 'wooooooooooooooooooooooooooooooooooooooooot' }, function(err, a) {
-    if (err) {
-      return done(err);
-    }
-
-    let pending = docs;
-    for (let i = 0; i < pending; ++i) {
-      new B({
-        as: [a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a],
-        a: a,
-        nested: [{ a: a }, { a: a }, { a: a }, { a: a }, { a: a }, { a: a }]
-      }).save(function(err) {
-        if (err) {
-          return done(err);
-        }
-        --pending;
-        if (pending === 0) {
-          // console.log('inserted %d docs. beginning test ...', docs);
-          start = Date.now();
-          test();
-        }
-      });
-    }
-  });
-});
-
-function test() {
-  let pending = 2;
-
-  B.find().populate('as').populate('a').populate('nested.a').exec(handle);
-  B.findOne().populate('as').populate('a').populate('nested.a').exec(handle);
-
-  function handle(err) {
-    if (err) {
-      throw err;
-    }
-    count++;
-
-    if (Date.now() - start > 1000 * 20) {
-      return done();
-    }
-
-    if (--pending === 0) {
-      return test();
-    }
-  }
-}
-
-
-function done(err) {
-  if (err) {
-    console.error(err.stack);
-  }
-
-  mongoose.connection.db.dropDatabase(function() {
-    mongoose.disconnect();
-    console.log('%d completed queries on mongoose version %s', count, mongoose.version);
-  });
-}
diff --git a/benchmarks/recursiveToObject.js b/benchmarks/recursiveToObject.js
new file mode 100644
index 0000000000..2760df44da
--- /dev/null
+++ b/benchmarks/recursiveToObject.js
@@ -0,0 +1,60 @@
+'use strict';
+
+const mongoose = require('../');
+
+run().catch(err => {
+  console.error(err);
+  process.exit(-1);
+});
+
+async function run() {
+  await mongoose.connect('mongodb://127.0.0.1:27017/mongoose_benchmark', {
+    serverSelectionTimeoutMS: 5000
+  });
+
+  const ChildSchema = new mongoose.Schema({ name: String, parentId: 'ObjectId' });
+  ChildSchema.virtual('answer').get(function() { return 42; });
+  const ChildModel = mongoose.model('Child', ChildSchema);
+
+  const ParentSchema = new mongoose.Schema({
+    name: String
+  });
+  ParentSchema.virtual('child1', { ref: 'Child', localField: '_id', foreignField: 'parentId' });
+  ParentSchema.virtual('child2', { ref: 'Child', localField: '_id', foreignField: 'parentId' });
+  ParentSchema.virtual('child3', { ref: 'Child', localField: '_id', foreignField: 'parentId' });
+  ParentSchema.virtual('child4', { ref: 'Child', localField: '_id', foreignField: 'parentId' });
+  const ParentModel = mongoose.model('Parent', ParentSchema);
+  
+  if (!process.env.MONGOOSE_BENCHMARK_SKIP_SETUP) {
+    await ParentModel.deleteMany({});
+    await ChildModel.deleteMany({});
+
+    const numDocs = 200;
+    const parents = [];
+    for (let i = 0; i < numDocs; ++i) {
+      const parent = await ParentModel.create({ name: 'test parent ' + i });
+      const children = [];
+      console.log(`${i} / ${numDocs}`);
+      for (let j = 0; j < numDocs; ++j) {
+        children.push({ name: 'test child ' + i + '_' + j, parentId: parent._id });
+      }
+      await ChildModel.create(children);
+      parents.push(parent);
+    }
+  }
+
+  const docs = await ParentModel.find().populate(['child1', 'child2', 'child3', 'child4']);
+  for (const doc of docs) {
+    doc.name = 'test parent';
+  }
+  const loopStart = Date.now();
+
+  docs.forEach(doc => doc.toObject({ virtuals: true }));
+
+  const results = {
+    'Total toObject time ms': Date.now() - loopStart
+  };
+
+  console.log(JSON.stringify(results, null, '  '));
+  process.exit(0);
+}
\ No newline at end of file
diff --git a/benchmarks/validate.js b/benchmarks/validate.js
deleted file mode 100644
index 97e4105199..0000000000
--- a/benchmarks/validate.js
+++ /dev/null
@@ -1,68 +0,0 @@
-'use strict';
-
-const mongoose = require('../../mongoose');
-const Benchmark = require('benchmark');
-
-const Schema = mongoose.Schema;
-const breakfastSchema = new Schema({
-  eggs: {
-    type: Number,
-    min: [6, 'Too few eggs'],
-    max: 12
-  },
-  bacon: {
-    type: Number,
-    required: [true, 'Why no bacon?']
-  },
-  drink: {
-    type: String,
-    enum: ['Coffee', 'Tea'],
-    required: function() {
-      return this.bacon > 3;
-    }
-  }
-});
-const Breakfast = mongoose.model('Breakfast', breakfastSchema);
-
-const badBreakfast = new Breakfast({
-  eggs: 2,
-  bacon: 0,
-  drink: 'Milk'
-});
-
-const goodBreakfast = new Breakfast({
-  eggs: 6,
-  bacon: 1,
-  drink: 'Tea'
-});
-
-const suite = new Benchmark.Suite();
-suite
-  .add('invalid async', {
-    defer: true,
-    fn: function(deferred) {
-      // avoid test inlining
-      suite.name;
-      badBreakfast.validate().catch(() => deferred.resolve());
-    }
-  })
-  .add('valid async', {
-    defer: true,
-    fn: function(deferred) {
-      // avoid test inlining
-      suite.name;
-      goodBreakfast.validate().then(() => deferred.resolve());
-    }
-  })
-  .add('invalid sync', function() {
-    badBreakfast.validateSync();
-  })
-  .add('valid sync', function() {
-    goodBreakfast.validateSync();
-  })
-  .on('cycle', function(evt) {
-    if (process.env.MONGOOSE_DEV || process.env.PULL_REQUEST) {
-      console.log(String(evt.target));
-    }
-  })
-  .run();
\ No newline at end of file

From 98f20f35e1d390ffb6cd9612ec14530d8fd2f725 Mon Sep 17 00:00:00 2001
From: Valeri Karpov <val@karpov.io>
Date: Fri, 31 May 2024 10:26:22 -0400
Subject: [PATCH 5/7] chore: remove unused dependency benchmark

---
 package.json | 1 -
 1 file changed, 1 deletion(-)

diff --git a/package.json b/package.json
index 975d46d682..a07cf63130 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,6 @@
     "assert-browserify": "2.0.0",
     "axios": "1.1.3",
     "babel-loader": "8.2.5",
-    "benchmark": "2.1.4",
     "broken-link-checker": "^0.7.8",
     "buffer": "^5.6.0",
     "cheerio": "1.0.0-rc.12",

From 75c6f8887901be602ca2291ef3d2ffd57b076507 Mon Sep 17 00:00:00 2001
From: Valeri Karpov <val@karpov.io>
Date: Fri, 31 May 2024 10:43:19 -0400
Subject: [PATCH 6/7] perf: memoize default toObject options on a per-schema
 basis re: #14394

---
 lib/document.js | 21 ++-------------------
 lib/schema.js   | 28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/lib/document.js b/lib/document.js
index bdb6e2e57d..8236fa820a 100644
--- a/lib/document.js
+++ b/lib/document.js
@@ -22,7 +22,6 @@ const clone = require('./helpers/clone');
 const compile = require('./helpers/document/compile').compile;
 const defineKey = require('./helpers/document/compile').defineKey;
 const flatten = require('./helpers/common').flatten;
-const get = require('./helpers/get');
 const getEmbeddedDiscriminatorPath = require('./helpers/document/getEmbeddedDiscriminatorPath');
 const getKeysInSchemaOrder = require('./helpers/schema/getKeysInSchemaOrder');
 const getSubdocumentStrictValue = require('./helpers/schema/getSubdocumentStrictValue');
@@ -3798,15 +3797,7 @@ Document.prototype.$__handleReject = function handleReject(err) {
  */
 
 Document.prototype.$toObject = function(options, json) {
-  const path = json ? 'toJSON' : 'toObject';
-  const baseOptions = this.constructor &&
-    this.constructor.base &&
-    this.constructor.base.options &&
-    get(this.constructor.base.options, path) || {};
-  const schemaOptions = this.$__schema && this.$__schema.options || {};
-  // merge base default options with Schema's set default options if available.
-  // `clone` is necessary here because `utils.options` directly modifies the second input.
-  const defaultOptions = Object.assign({}, baseOptions, schemaOptions[path]);
+  const defaultOptions = this.$__schema._getDefaultToObjectOptions();
 
   // If options do not exist or is not an object, set it to empty object
   options = utils.isPOJO(options) ? { ...options } : {};
@@ -3815,10 +3806,8 @@ Document.prototype.$toObject = function(options, json) {
   let _minimize;
   if (options._calledWithOptions.minimize != null) {
     _minimize = options.minimize;
-  } else if (defaultOptions.minimize != null) {
-    _minimize = defaultOptions.minimize;
   } else {
-    _minimize = schemaOptions.minimize;
+    _minimize = defaultOptions.minimize;
   }
 
   options.minimize = _minimize;
@@ -3842,14 +3831,8 @@ Document.prototype.$toObject = function(options, json) {
   }
   options._isNested = true;
   options.json = json;
-  options.minimize = _minimize;
-
   options._parentOptions = options;
-
   options._skipSingleNestedGetters = false;
-  // remember the root transform function
-  // to save it from being overwritten by sub-transform functions
-  // const originalTransform = options.transform;
 
   let ret = clone(this._doc, options) || {};
 
diff --git a/lib/schema.js b/lib/schema.js
index 4dfefccf54..96de706ed2 100644
--- a/lib/schema.js
+++ b/lib/schema.js
@@ -128,6 +128,7 @@ function Schema(obj, options) {
   // For internal debugging. Do not use this to try to save a schema in MDB.
   this.$id = ++id;
   this.mapPaths = [];
+  this._defaultToObjectOptions = null;
 
   this.s = {
     hooks: new Kareem()
@@ -2597,6 +2598,33 @@ Schema.prototype.loadClass = function(model, virtualsOnly) {
   return this;
 };
 
+/**
+ * Returns default `toObject` / `toJSON` options for this schema,
+ * combining the associated
+ *
+ * @param {Boolean} json
+ * @returns object
+ */
+
+Schema.prototype._getDefaultToObjectOptions = function _getDefaultToObjectOptions(json) {
+  const path = json ? 'toJSON' : 'toObject';
+
+  if (this._defaultToObjectOptions && this._defaultToObjectOptions[path]) {
+    return this._defaultToObjectOptions[path];
+  }
+
+  const baseOptions = this.base && this.base.options && this.base.options[path];
+  const schemaOptions = this.options && this.options[path];
+  const defaultOptions = Object.assign(
+    {},
+    baseOptions,
+    schemaOptions
+  );
+  this._defaultToObjectOptions = this._defaultToObjectOptions || {};
+  this._defaultToObjectOptions[path] = defaultOptions;
+  return defaultOptions;
+};
+
 /*!
  * ignore
  */

From c26fda01a8e4eccc4f0f362d7298e22b220bc155 Mon Sep 17 00:00:00 2001
From: Valeri Karpov <val@karpov.io>
Date: Fri, 31 May 2024 11:02:27 -0400
Subject: [PATCH 7/7] Revert "perf: memoize default toObject options on a
 per-schema basis re: #14394"

This reverts commit 75c6f8887901be602ca2291ef3d2ffd57b076507.
---
 lib/document.js | 21 +++++++++++++++++++--
 lib/schema.js   | 28 ----------------------------
 2 files changed, 19 insertions(+), 30 deletions(-)

diff --git a/lib/document.js b/lib/document.js
index 8236fa820a..bdb6e2e57d 100644
--- a/lib/document.js
+++ b/lib/document.js
@@ -22,6 +22,7 @@ const clone = require('./helpers/clone');
 const compile = require('./helpers/document/compile').compile;
 const defineKey = require('./helpers/document/compile').defineKey;
 const flatten = require('./helpers/common').flatten;
+const get = require('./helpers/get');
 const getEmbeddedDiscriminatorPath = require('./helpers/document/getEmbeddedDiscriminatorPath');
 const getKeysInSchemaOrder = require('./helpers/schema/getKeysInSchemaOrder');
 const getSubdocumentStrictValue = require('./helpers/schema/getSubdocumentStrictValue');
@@ -3797,7 +3798,15 @@ Document.prototype.$__handleReject = function handleReject(err) {
  */
 
 Document.prototype.$toObject = function(options, json) {
-  const defaultOptions = this.$__schema._getDefaultToObjectOptions();
+  const path = json ? 'toJSON' : 'toObject';
+  const baseOptions = this.constructor &&
+    this.constructor.base &&
+    this.constructor.base.options &&
+    get(this.constructor.base.options, path) || {};
+  const schemaOptions = this.$__schema && this.$__schema.options || {};
+  // merge base default options with Schema's set default options if available.
+  // `clone` is necessary here because `utils.options` directly modifies the second input.
+  const defaultOptions = Object.assign({}, baseOptions, schemaOptions[path]);
 
   // If options do not exist or is not an object, set it to empty object
   options = utils.isPOJO(options) ? { ...options } : {};
@@ -3806,8 +3815,10 @@ Document.prototype.$toObject = function(options, json) {
   let _minimize;
   if (options._calledWithOptions.minimize != null) {
     _minimize = options.minimize;
-  } else {
+  } else if (defaultOptions.minimize != null) {
     _minimize = defaultOptions.minimize;
+  } else {
+    _minimize = schemaOptions.minimize;
   }
 
   options.minimize = _minimize;
@@ -3831,8 +3842,14 @@ Document.prototype.$toObject = function(options, json) {
   }
   options._isNested = true;
   options.json = json;
+  options.minimize = _minimize;
+
   options._parentOptions = options;
+
   options._skipSingleNestedGetters = false;
+  // remember the root transform function
+  // to save it from being overwritten by sub-transform functions
+  // const originalTransform = options.transform;
 
   let ret = clone(this._doc, options) || {};
 
diff --git a/lib/schema.js b/lib/schema.js
index 96de706ed2..4dfefccf54 100644
--- a/lib/schema.js
+++ b/lib/schema.js
@@ -128,7 +128,6 @@ function Schema(obj, options) {
   // For internal debugging. Do not use this to try to save a schema in MDB.
   this.$id = ++id;
   this.mapPaths = [];
-  this._defaultToObjectOptions = null;
 
   this.s = {
     hooks: new Kareem()
@@ -2598,33 +2597,6 @@ Schema.prototype.loadClass = function(model, virtualsOnly) {
   return this;
 };
 
-/**
- * Returns default `toObject` / `toJSON` options for this schema,
- * combining the associated
- *
- * @param {Boolean} json
- * @returns object
- */
-
-Schema.prototype._getDefaultToObjectOptions = function _getDefaultToObjectOptions(json) {
-  const path = json ? 'toJSON' : 'toObject';
-
-  if (this._defaultToObjectOptions && this._defaultToObjectOptions[path]) {
-    return this._defaultToObjectOptions[path];
-  }
-
-  const baseOptions = this.base && this.base.options && this.base.options[path];
-  const schemaOptions = this.options && this.options[path];
-  const defaultOptions = Object.assign(
-    {},
-    baseOptions,
-    schemaOptions
-  );
-  this._defaultToObjectOptions = this._defaultToObjectOptions || {};
-  this._defaultToObjectOptions[path] = defaultOptions;
-  return defaultOptions;
-};
-
 /*!
  * ignore
  */